DOL Design System - Practice Patterns
Practice Patterns
Section titled “Practice Patterns”Extends CORE.md. Dành cho Exercise, Exercise with AI, Online Test. Đọc CORE.md trước - file này chỉ chứa patterns đặc thù cho Practice. Product logic như score band, attempt rule, leaderboard metric, unlock/deadline, hoặc thứ tự material phải được product/spec xác nhận; file này chỉ ghi reusable UI implications để designer/dev không phải suy luận lại từ đầu.
§1 Exercise Layout status:done
Section titled “§1 Exercise Layout status:done”Extends CORE.md §4 Spacing + §6 Surface + §9 Components. Playground refs:
components/Practice/AttemptView.tsx,components/Playground/Exercise2026Idea.tsx.
1.1 Exercise Page Shell
Section titled “1.1 Exercise Page Shell”One question, one focus - exercise page strip chrome, center user attention on active question.
Three-region shell:
┌─────────────────────────────┐│ Header (skill + progress) │ ← sticky top, thin├─────────────────────────────┤│ ││ Body (prompt + answers) │ ← scrollable, main focus│ │├─────────────────────────────┤│ Footer (submit / next) │ ← sticky bottom OR inline└─────────────────────────────┘- Header:
h-14 sticky top-0 bg-white border-b border-slate-100với skill icon + progress indicator. No page nav (user đã in exercise mode). - Body:
px-4 py-6 md:px-8 md:py-10 max-w-3xl mx-auto- centered, readable width (~700-800px). Prevents reading marathon trên wide screens (DIRECTION §10 Layout). - Footer:
sticky bottom-0 bg-white border-t border-slate-100cho long exercises; inline dưới body cho short exercises.
1.2 Question Panel
Section titled “1.2 Question Panel”Question region: prompt + optional media (audio, image) + instructions.
| Element | Class | Notes |
|---|---|---|
| Prompt text | text-lg font-medium text-slate-900 hoặc text-xl font-semibold | lg cho most cases; xl khi prompt quan trọng hơn answer |
| Media (audio/image) | Below prompt, max-w-full rounded-xl | Giữ aspect ratio; media không lấn prompt readability |
| Instructions | text-sm text-slate-600 trước answer area | Optional; only khi exercise type cần explain |
| Prompt → Answer gap | mt-6 (C-organism per CORE §4.1) | Separates question context from action area |
1.3 Answer Area Sizing
Section titled “1.3 Answer Area Sizing”Layout depends on answer type:
| Answer Type | Layout | Sizing |
|---|---|---|
| Multiple choice (2-4 options) | Stacked vertical | Full-width cards space-y-3 |
| Multiple choice (5-8 options) | 2-column grid | grid grid-cols-1 md:grid-cols-2 gap-3 |
| True/False | Horizontal pair | grid grid-cols-2 gap-3 |
| Fill-in-blank | Inline with prompt | Input w-32 (short) hoặc w-full (long) |
| Free text / essay | Full-width textarea | w-full min-h-[120px] max-h-[400px] |
| Speaking / recording | Record button centered | Button h-14 centered, mt-6 |
1.4 Split-panel Pattern (long-form)
Section titled “1.4 Split-panel Pattern (long-form)”Khi prompt dài (reading passage, listening transcript) → split-panel ≥ lg:
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6"> <div className="lg:sticky lg:top-20 lg:max-h-[calc(100vh-8rem)] lg:overflow-y-auto"> {/* prompt (reading passage / transcript) */} </div> <div> {/* answers */} </div></div>- Breakpoint:
lg(≥1024px). Below: stack (prompt trước, answers sau). - Sticky prompt while user scrolls answers - user reference passage while answering.
max-h-[calc(100vh-8rem)]+overflow-y-autotrong prompt panel - scroll independently.- Không bao giờ 3-column split (reading flow gãy).
1.5 Responsive Stacking
Section titled “1.5 Responsive Stacking”| Breakpoint | Behavior |
|---|---|
| < md (mobile) | Always stack vertical. Full-width actions. |
| md-lg (tablet) | Stack for split-panel; side-by-side for short prompts |
| ≥ lg (desktop) | Split-panel activates for long-form |
- Header giữ sticky mọi breakpoint (progress context always visible)
- Footer: full-width button mobile, inline tablet+
- Không force 2-column split mobile (reading flow broken)
§2 Answer Cards status:done
Section titled “§2 Answer Cards status:done”Extends CORE.md §9.1 Card + §2.3 Status Colors. Answer cards = core interactive primitive của Practice - phải consistent across exercise types.
2.1 Default State
Section titled “2.1 Default State”Touchable, not flashy - answer card mời chạm nhưng không overwhelm prompt. Extends CORE §9.1 Card với interaction layer.
<button type="button" className="w-full text-left p-4 rounded-xl border border-slate-200 bg-white hover:border-slate-300 hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-colors duration-200 text-slate-900"> {answer.text}</button>- Padding:
p-4(inset-4 per CORE §4.1) - breathable, không loose - Radius:
rounded-xl(12px) - soft-large per DIRECTION §8 - Border:
border-slate-200default,border-slate-300hover (subtle, không flash) - Focus ring:
ring-2 ring-blue-500/20- CORE focus pattern - Transition:
duration-200color-only (no layout animation per R11 slop-09)
2.2 Selected State (pre-submit)
Section titled “2.2 Selected State (pre-submit)”User clicks answer → selected, chưa submit.
className={cn( base, isSelected && "border-blue-500 bg-blue-50 ring-2 ring-blue-500/10")}- Border:
border-blue-500(info-primary = active state) - Background tint:
bg-blue-50(info dim bg per CORE §2.3) - Optional subtle ring:
ring-2 ring-blue-500/10
Không dùng brand red cho selected - brand reserved cho CTA/logo (DIRECTION §4). Info color = active state per DOL convention.
2.3 Correct State (post-submit)
Section titled “2.3 Correct State (post-submit)”After submit, correct answer gets success treatment.
className={cn( base, isCorrect && "border-green-500 bg-green-50 text-slate-900")}- Border:
border-green-500 - Background:
bg-green-50 - Optional
<Check />icon right-alignedtext-green-600 - Extends CORE §2.3 Status Colors (success dim bg + primary border)
- Text giữ
text-slate-900- không đổi sang green (maintains readability)
2.4 Incorrect State (post-submit)
Section titled “2.4 Incorrect State (post-submit)”After submit, user’s incorrect answer gets danger treatment - visible nhưng không hostile.
className={cn( base, isIncorrect && "border-red-500 bg-red-50 text-slate-900")}- Border:
border-red-500 - Background:
bg-red-50 - Optional
<X />icon right-alignedtext-red-600 - Không shake/bounce animation (R11 slop-08); subtle color transition 200ms là đủ
- Tone: informative, không punitive. DOL = education, wrong answer là learning moment, không là failure.
2.5 Review State (neutral, read-only)
Section titled “2.5 Review State (neutral, read-only)”Viewing past attempts / completed exercise → cards non-interactive.
// button → div when review modeclassName={cn( base, isReviewMode && "cursor-default hover:border-slate-200 hover:bg-white")}- Remove hover state (non-interactive)
- Giữ correct/incorrect color treatment nếu reviewing attempts
- Disable click handler; button → div với
role="group" - Wrap với label “Đáp án đúng” / “Bạn chọn” above mỗi card để clarify context
2.6 Anti-patterns
Section titled “2.6 Anti-patterns”🛑 Match-and-refuse (per DIRECTION §10): nếu bạn sắp generate code khớp một row dưới, STOP - rewrite approach từ đầu, không chỉ swap value lẻ.
<dol_anti_pattern scope=“practice-2.6-answer-cards”>
| ID | ❌ PATTERN | Vì sao | ✅ REWRITE |
|---|---|---|---|
| 01 | Shake / bounce animation on incorrect | R11 slop-08 bounce feel; feels punitive, wrong DOL education tone | Subtle color transition 200ms ease-out |
| 02 | Brand red for “selected” state | Brand reserved cho CTA/logo (DIRECTION §4); confuses với danger | Blue for selected (info = active per DOL convention) |
| 03 | Full border + bg + shadow change on hover | R11 slop-07 over-treatment | Border color change only, hoặc bg tint only, not all three |
| 04 | Icon badge above answer text | Icon-tile-above slop (R11 slop-06); wastes visual weight | Inline icon right-aligned, hoặc skip entirely |
| 05 | Gradient bg on correct/incorrect | R11 slop-02 decoration without meaning | Flat bg-{color}-50 tint (CORE §2.3) |
| 06 | Huge letter prefix “A” / “B” / “C” as badge | Pulls weight from answer content (user reads letter, not text) | Letter inline: text-slate-500 font-medium mr-3, or skip if answers text alone is clear |
| 07 | ”Try again” text on incorrect | Punitive phrasing; DOL tone is calm | Explanation + next-action button inline, không text reprimand |
| 08 | Confetti / celebration animation on correct | Marketing-gamification, wrong for learning context | Quiet success indicator; reserve celebration cho milestone (chapter complete) |
</dol_anti_pattern>
§3 AI Content Discipline status:done
Section titled “§3 AI Content Discipline status:done”Rules cho AI-generated content rendering trên Practice surfaces.
3.1 Semantic Highlight Scope
Section titled “3.1 Semantic Highlight Scope”AI content chỉ highlight 3 nhóm:
| Nhóm | Ví dụ | Style |
|---|---|---|
| Core skill names | Reading, Listening, Speaking, Writing, Vocabulary, Grammar, Pronunciation | Tint inline nhẹ, đọc được trong paragraph flow |
| Lesson target / subskill | Relative Clauses, Paraphrasing, Intonation | Tint inline, chỉ khi thật sự quan trọng |
| Study metrics / data | 77%, Band 6.5, 15 phút, 3/5 bài | Neutral data-pill, tabular-nums |
- Mỗi paragraph chỉ vài semantic highlights đáng chú ý.
- Nếu content đã dày →
**bold**cho emphasis phụ thay vì tô màu. - KHÔNG biến highlight thành badge nặng trong body copy.
3.2 Signal Cards
Section titled “3.2 Signal Cards”- Oversized value chỉ cho metric-like values:
%,band, số lượng, thời lượng, count. - Topic/status text (
Relative Clauses,Đang ổn,Cần sửa) giữ ở 14px body scale. - Signal card không được phồng typography.
3.3 Fact Rows
Section titled “3.3 Fact Rows”AI diagnostic rows (label:value format):
Rủi ro: Relative ClausesCompletion: 77%Điểm mạnh: Vocabulary in Context- Label ngắn, value là phần chính.
- Đi qua shared
fact rowformatting. - KHÔNG biến thành card con hoặc dashboard nặng.
3.4 Markdown Rendering
Section titled “3.4 Markdown Rendering”AI content phải đi qua shared markdown renderer:
Inline semantics (baseline): bold, italic, code, link, strikethrough, highlight.
Block semantics (baseline): heading, list, task list, blockquote, divider, code block, labeled callout.
- KHÔNG để raw markers (
**bold**,*italic*,~~strike~~,`code`) lọt ra production. - Mở rộng semantics → thêm vào shared renderer trước, không patch riêng từng lane.
- Checklist, list, callout, paragraph, signal value → cùng markdown preview behavior.
3.5 Copy Rules
Section titled “3.5 Copy Rules”- Utility copy tiếng Việt nhất quán:
Xem thêm,Thu gọn,Tạo lại. - KHÔNG mixed-language drift trên AI surfaces.
- Không kéo marketing narrative vào logged-in surfaces.
§4 Timer & Progress status:done
Section titled “§4 Timer & Progress status:done”Extends CORE.md §2.3 Status Colors + §3 Typography + §10 Motion. Practice time + progress tracking UX.
4.1 Timer Component
Section titled “4.1 Timer Component”Two modes: countdown (timed tests - IELTS simulation) + elapsed (untimed practice).
Countdown (shows time remaining):
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white border border-slate-200 text-slate-900 tabular-nums"> <Clock className="w-4 h-4 text-slate-500" /> <span className="font-semibold">{formatTime(timeRemaining)}</span></div>- Layout: pill shape, sticky top near skill indicator
- Font:
tabular-nums- prevents width shift between00:45và01:30 - Color progression (urgency without panic):
-
50% remaining: neutral
text-slate-900 - 25-50%:
text-amber-600+border-amber-200 bg-amber-50 - <25%:
text-red-600+border-red-200 bg-red-50 - =0: see §4.4 Time-up state
-
Elapsed (untimed): same structure, skip color progression - stays neutral throughout.
4.2 Linear Progress Bar
Section titled “4.2 Linear Progress Bar”Question-by-question / skill-section progress:
<div className="w-full h-1.5 bg-slate-100 rounded-full overflow-hidden"> <div className="h-full bg-brand-600 transition-all duration-500 ease-out rounded-full" style={{ width: `${(current / total) * 100}%` }} /></div>- Height:
h-1.5(6px) - subtle, không compete với content - Track:
bg-slate-100; fill:bg-brand-600default orbg-{skill}-600khi có skill context - Transition:
duration-500 ease-out- smooth update (no bounce per R11 slop-08)
4.3 Step Indicator (Question Navigator)
Section titled “4.3 Step Indicator (Question Navigator)”Horizontal dots showing question statuses:
<div className="flex items-center gap-1.5 flex-wrap"> {questions.map((q, i) => ( <button key={q.id} className={cn( "w-8 h-8 rounded-full text-xs font-semibold transition-colors", q.answered && !q.current && "bg-slate-100 text-slate-600", q.current && "bg-brand-600 text-on-inverse-primary", !q.answered && !q.current && "bg-white border border-slate-200 text-slate-400" )} aria-label={`Câu ${i + 1}${q.current ? ' (hiện tại)' : q.answered ? ' (đã trả lời)' : ' (chưa trả lời)'}`} > {i + 1} </button> ))}</div>- Answered (not current):
bg-slate-100 text-slate-600(done, neutral) - Current:
bg-brand-600 text-on-inverse-primary(active focus) - Pending:
bg-white border-slate-200 text-slate-400(not yet reached) - Clickable cho review/jump; horizontal scroll wrapper khi >10 questions
4.4 Time-up State
Section titled “4.4 Time-up State”Khi countdown = 0: calm VN alert + UI transition:
{isTimeUp && ( <div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-red-50 border border-red-200 text-red-700 font-semibold"> <AlertCircle className="w-4 h-4" /> Hết giờ </div>)}- Clear VN label “Hết giờ”
- Auto-submit form if configured, else freeze input + show result option
- Không blink/flash effect - DOL education tone stays calm (R11 slop-08 bounce territory)
- References CORE §2.3 Status Colors danger dim bg
4.5 Anti-patterns
Section titled “4.5 Anti-patterns”🛑 Match-and-refuse (per DIRECTION §10): nếu bạn sắp generate code khớp một row dưới, STOP - rewrite approach từ đầu, không chỉ swap value lẻ.
<dol_anti_pattern scope=“practice-4.5-timer-progress”>
| ID | ❌ PATTERN | Vì sao | ✅ REWRITE |
|---|---|---|---|
| 01 | Red flash / blink when time <1 min | Stress-inducing, punitive - wrong DOL tone | Color progression (neutral → amber → red) via static colors |
| 02 | Timer font không tabular-nums | Width shifts mỗi second; visual jitter | Always tabular-nums for time displays |
| 03 | Progress bar bounce/elastic easing | R11 slop-08; feels playful trong wrong context | ease-out duration-500 linear smooth |
| 04 | Circular progress với huge % text center | Hero-metric slop; competes với question | Slim horizontal bar + small % text nếu cần |
| 05 | Step indicator có label “Câu 3 of 10” + dots đồng thời | Redundant - dot count = total | Dots only OR “3/10” text only, không both |
| 06 | Auto-submit không warning | User mất answers chưa commit; surprise UX | 30s warning toast trước time-up |
</dol_anti_pattern>
§5 Skill Color Usage in Practice status:done
Section titled “§5 Skill Color Usage in Practice status:done”Skill colors (from CORE.md §2.4) apply trong Practice context:
| Element | Áp dụng skill color |
|---|---|
| Question section header | Tint background theo skill |
| Score/result badge | Skill color badge |
| Progress per skill | Skill color cho progress bar |
| Navigation tab | Subtle tint khi active |
Xem CORE.md §2.4 cho bảng skill → TW family mapping.
§6 Audio / TTS Integration status:done
Section titled “§6 Audio / TTS Integration status:done”Extends CORE.md §9.2 Button + §10 Motion. UI-side patterns cho audio controls. Audio engine / TTS pipeline detail: see
audio-ttsskill (workspace.claude/skills/).
6.1 Audio Player UI
Section titled “6.1 Audio Player UI”Standard playback controls: play/pause + progress + duration.
<div className="flex items-center gap-3 p-3 rounded-xl bg-slate-50 border border-slate-100"> <button onClick={togglePlay} aria-label={isPlaying ? "Tạm dừng" : "Phát"} className="w-10 h-10 rounded-full bg-brand-600 text-on-inverse-primary hover:bg-brand-700 flex items-center justify-center transition-colors duration-200" > {isPlaying ? <Pause className="w-4 h-4" /> : <Play className="w-4 h-4 ml-0.5" />} </button> <div className="flex-1"> <div className="h-1 bg-slate-200 rounded-full overflow-hidden"> <div className="h-full bg-slate-600 transition-all" style={{ width: `${progress * 100}%` }} /> </div> </div> <span className="text-xs text-slate-500 tabular-nums"> {formatTime(current)} / {formatTime(duration)} </span></div>- Container:
rounded-xl bg-slate-50 border border-slate-100subtle surface per CORE §6 - Play button:
w-10 h-10circular brand color - core action - Progress:
h-1thin track (support role, không focal) - Time display:
tabular-numsgiữ digit width stable
6.2 Mute Toggle
Section titled “6.2 Mute Toggle”Persistent mute state across practice session:
<button onClick={toggleMute} aria-label={isMuted ? "Bật âm thanh" : "Tắt âm thanh"} aria-pressed={isMuted} className="p-2 rounded-lg hover:bg-slate-100 text-slate-600 transition-colors"> {isMuted ? <VolumeX className="w-5 h-5" /> : <Volume2 className="w-5 h-5" />}</button>- Placement: header area, near skill/progress indicators
- State persistence: store preference trong
localStorage- maintain across sessions - Icon swap:
Volume2/VolumeXfrom Lucide - Không auto-unmute khi user explicitly muted - respect choice
6.3 Feedback Sound UX
Section titled “6.3 Feedback Sound UX”Correct/incorrect/complete notification sounds - optional, accessible:
| Sound | Characteristic | Volume | Duration |
|---|---|---|---|
| Correct | Soft chime - pleasant, not celebratory | 30-40% | <500ms |
| Incorrect | Gentle low tone - informative, not punitive | 30-40% | <500ms |
| Section complete | Short rising melody - achievement cue | 40-50% | ~800ms |
A11y mandate:
- All feedback sounds HAVE visual counterpart (check icon / x icon per §2 Answer Cards)
- Respect
prefers-reduced-motion: nếu user có preference → auto-mute feedback sounds - User can disable via settings - preference persists per §6.2 pattern
- Never rely on sound alone cho critical state feedback
6.4 Narration Indicator (Speaking Animation)
Section titled “6.4 Narration Indicator (Speaking Animation)”Visual cue khi AI TTS narration is playing:
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-sky-50 border border-sky-200 text-sky-700"> <div className="flex items-end gap-0.5 h-3"> <span className="w-0.5 bg-sky-600 animate-pulse-bar-1" /> <span className="w-0.5 bg-sky-600 animate-pulse-bar-2" /> <span className="w-0.5 bg-sky-600 animate-pulse-bar-3" /> </div> <span className="text-xs font-medium">Đang nói...</span></div>- Color:
sky-*(AI features per CORE §2.4 skill colors) - Animation: 3 pulsing bars với staggered delay (0s / 0.2s / 0.4s) - audio-level indicator pattern
- VN label: “Đang nói…” / “Đang giải thích…”
- Auto-dismiss khi narration ends
6.5 Anti-patterns
Section titled “6.5 Anti-patterns”🛑 Match-and-refuse (per DIRECTION §10): nếu bạn sắp generate code khớp một row dưới, STOP - rewrite approach từ đầu, không chỉ swap value lẻ.
<dol_anti_pattern scope=“practice-6.5-audio-tts”>
| ID | ❌ PATTERN | Vì sao | ✅ REWRITE |
|---|---|---|---|
| 01 | Loud feedback sounds (100% volume) | Jarring, disrupts focus | 30-40% volume, <500ms duration |
| 02 | Harsh buzzer for incorrect | Punitive tone, wrong DOL education feel | Gentle low tone - informative, not scolding |
| 03 | Auto-play narration without user initiate | Surprises user trong public places; consent violation | Require explicit play button tap |
| 04 | Narration indicator using brand color | Brand reserved cho CTA/logo; confuses semantics | sky-* (AI identity per DOL skill colors) |
| 05 | No visual counterpart cho audio feedback | A11y fail cho deaf users / muted context | Pair audio với visual (check icon, toast) |
| 06 | Progress bar bounce/elastic during playback | R11 slop-08 bounce; dated feel | Linear smooth transition; no overshoot |
| 07 | Vague labels (“Play”, “Pause” in English) | Mixed-language drift trong VN UI | Full VN: “Phát”, “Tạm dừng”, “Đang nói…” |
</dol_anti_pattern>
§7 Product Logic References status:done
Section titled “§7 Product Logic References status:done”Synthesized from current Design Hub product-pattern pages: Online Test logic, Status test, UI Score, Score level, Leaderboard, Attempt history, and exercise-ordering reference. DS-Token keeps the reusable UI implications here; EduDoc/product owner remains source of truth for scoring, data model, permission, and business rules.
7.1 Online Test Structure
Section titled “7.1 Online Test Structure”Default mental model:
[optional] Skill -> Section -> [optional] Group -> QuestionUse this model when designing flow, progress, review, scoring, or result screens:
| Level | UI implication | Check before reuse |
|---|---|---|
| Skill | Top-level tab/segment or result breakdown for Reading, Listening, Writing, Speaking, Test | Does product actually split by skill? |
| Section | Major test part, passage, task type, or content block | Does navigation/progress follow section or question? |
| Group | Shared passage/media/context for >=2 related questions | Does the group need split-panel, sticky prompt, or shared audio/image? |
| Question | Smallest answerable unit | Are type, input, scoring, explanation, and review state clear? |
If the product has no skill split, start from Section. If questions share passage/media, prefer Group rather than repeating context per question.
7.2 Test / Practice Lifecycle States
Section titled “7.2 Test / Practice Lifecycle States”Practice/test cards, rows, and navigation should distinguish lifecycle state from visual decoration.
| State | Meaning | UI requirement |
|---|---|---|
| Locked | User cannot access yet | Disabled/locked affordance + reason/unlock condition if available |
| Waiting / Not opened | Available later or not started | Neutral state + clear start/open timing |
| In progress | Current attempt exists | Primary/current affordance + progress context |
| Done / Closed | Completed or closed for submission | Result/review affordance; do not imply editable if closed |
| Warning | Needs attention before becoming error | Warning label + action or explanation |
| Error | Failed/invalid/blocking problem | Error label + recovery path |
Rules:
- State must affect CTA/navigation when relevant, not only badge color.
- Do not rely on color alone; include label/icon/context.
- If a state is both skill-related and status-related, status color wins; skill color stays in surrounding context.
7.3 Result and Score UI
Section titled “7.3 Result and Score UI”Result UI should help learners understand what happened and what to do next. A useful result screen usually includes:
- Score/result summary: score, band, percent, pass/fail, or main outcome.
- Context: attempt, total questions, skill/section, time, benchmark, or previous result if useful.
- Breakdown: correct/incorrect/skipped, skill/topic, section, or group-level performance.
- Feedback: short, specific, non-punitive explanation.
- Next action: review mistakes, practice again, continue lesson, retake, view explanation, or ask AI.
Score rules:
- Product/spec must confirm score band, threshold, and meaning.
- Low score is not automatically danger; it may be learning feedback.
- High score is not automatically success if no completion/achievement has occurred.
- Score color must not conflict with error/warning/success states on the same screen.
7.4 Leaderboard and Ranking
Section titled “7.4 Leaderboard and Ranking”Use leaderboard only when there is a real comparison mechanic.
Before designing leaderboard UI, confirm:
- Metric: score, time, accuracy, completion, streak, or composite score.
- Scope: class, cohort, course, practice set, assignment, or global board.
- Rank logic: top 3/top 4/top 8/top 10, tie handling, and hidden/private users.
- Attempt rule: latest, best, first N attempts, or product-specific counted attempts.
- Current user visibility and empty/loading/error states.
Visual rules:
- Ranking emphasis is not generic accent color and not status color.
- Top 1/2/3/other may use distinct treatments, but they must stay subordinate to task CTA and result clarity.
- If leaderboard coexists with personal score feedback, separate ranking from learning feedback in layout and copy.
7.5 Attempt History
Section titled “7.5 Attempt History”Attempt history supports review, comparison, and explaining why score/rank changed.
Required states:
- No attempt yet.
- Current/latest attempt.
- Past attempt.
- Attempt not counted in leaderboard.
- AI attempt limit reached, if AI practice has a separate quota.
- Loading/error while fetching history.
Rules:
- Opening an old attempt should enter review/read-only mode unless it is the current active attempt.
- UI must say which attempt affects score summary or leaderboard when ranking is present.
- GV/HV visibility may differ; confirm permissions with product/spec before exposing attempt detail.
7.6 Exercise / Material Ordering Reference
Section titled “7.6 Exercise / Material Ordering Reference”Current product reference order for Course materials / Bài tập trong khóa:
- Assignments
- Online tests
- Dictation
- Vocabulary
- Exercises
- AI mock test
- Mental model
- Sample W/S
- Blog, Video, PDF
- Roadmap cá nhân hóa
Before reusing this order:
- Confirm role: GV, HV, or operations role.
- Confirm surface: course material, homework list, learning roadmap, or another product lane.
- Check permission/lock/deadline conditions that may hide or reorder items.
- Ask product owner if applying this order to a new product, because this is a product reference, not universal DS hierarchy.
7.7 Product-pattern Verification Checklist
Section titled “7.7 Product-pattern Verification Checklist”Before shipping a Practice/Test surface:
- Does the UI model match skill/section/group/question structure?
- Are lifecycle states explicit in label/icon/context and CTA behavior?
- Are score bands, thresholds, and ranking rules confirmed by product/spec?
- Is old attempt review read-only?
- Does leaderboard state clearly say what metric and attempt rule are counted?
- Are status color, skill color, and ranking color separated by meaning?
- Is the next learner action clear after result/feedback?