EVALUATE
They would first understand where the student currently stands.
SAT LMS
No browsing. No guessing. Just learning.
The LMS diagnoses each student's strengths and gaps, curates only the concepts they need, and turns the course into a clear action plan — not another library to browse.
Logos are properties of their respective companies.
TL;DR
My Impact
32%
Next-step continuation?Measures how often students start the next recommended activity immediately after completing one.This improved by making the next step explicit, removing alternate paths, and keeping the user in a continuous flow instead of returning them to a menu.
up from 32%
52%
Progress depth?Measures how much of the system-recommended path a student completes before dropping off.This increased by structuring the course into guided, adaptive paths, ensuring students only see what they need and do not get lost in the full syllabus.
up from 52%
112 sec
Time to first meaningful action?Measures how long it takes for a student to start their first learning activity after opening the app.Reduced by removing setup decisions and surfacing a single, immediate next action, so users can start learning without figuring out where to begin.
down from 1 min 52 sec
The Problem
Before designing the LMS, I looked at student conversations outside the product. The problem was not missing content. It was missing direction: students had practice and explanations, but still did not know which gap to fix next.
Student signals · hover on a card to pause
“I don’t feel like I’m learning anything useful…”
Practice was happening, but it was not reliably translating into understanding or progress.
“The explanations… don’t teach the concepts involved.”
Students could review answers, but not always learn the underlying concept well enough to transfer.
“I fundamentally don’t know…”
Many students were not just making mistakes — they were missing buried foundations the system failed to surface.
“Here’s 800 pages… weak spots get two problems.”
The market had enough material, but not enough intelligence to decide what deserved attention for each student.
Logos are properties of their respective companies.
Students didn’t need another content dump. They needed a system that diagnoses, prioritizes, and prescribes what to learn - an intelligent tutor!
My approach
Once the problem was clear, I asked the question —
If the student were working with a private tutor,
what would the tutor do for them?
They would first understand where the student currently stands.
A tutor would channel effort toward what needs to be learned next, instead of making the student learn everything.
A tutor would keep setbacks from becoming dead ends. They would give the next useful action.
I began thinking of the LMS not as a place to browse courses, but as an intelligent tutor.
Key design decisions
Decision01
Decision aim
Establish the student's starting point before the LMS prescribes anything.
Product decision
Students should begin the course with the diagnostic, so the LMS can understand their level before shaping the path.
UX support
I kept it prominent until it was taken through the hero advisory, the recommended first card, and friction that warned against skipping ahead.
Decision02
Decision aim
Make personalization feel trustworthy by showing the logic behind the changed path.
Product decision
After the diagnostic, students should get a path shaped by what they know, what they can skip, and what still needs proof.
UX support
I made that payoff visible through recommended items, skipped content, proof checkpoints, and time saved, so the path felt like the reward for effort.
Decision03
Decision aim
Keep students moving through the right next activity instead of returning them to a syllabus.
Product decision
Once the path is known, the course should keep prescribing what to do next instead of asking students to browse the full syllabus.
UX support
I centered the page around Next Up, the current module, and resume learning, while keeping broader exploration available but secondary.
Decision04
Decision aim
Turn low-score and return moments into clear recovery instead of self-diagnosis.
Product decision
When students underperform or return after a break, the LMS should generate a recovery path instead of leaving them to self-correct.
UX support
The recovery state should show what happened and surface a clear remedial or revision action, so students restart from motion, not confusion.
01
Decision aim
Establish the student's starting point before the LMS prescribes anything.
Product decision
Students should begin the course with the diagnostic, so the LMS can understand their level before shaping the path.
UX support
I kept it prominent until it was taken through the hero advisory, the recommended first card, and friction that warned against skipping ahead.
02
Decision aim
Make personalization feel trustworthy by showing the logic behind the changed path.
Product decision
After the diagnostic, students should get a path shaped by what they know, what they can skip, and what still needs proof.
UX support
I made that payoff visible through recommended items, skipped content, proof checkpoints, and time saved, so the path felt like the reward for effort.
03
Decision aim
Keep students moving through the right next activity instead of returning them to a syllabus.
Product decision
Once the path is known, the course should keep prescribing what to do next instead of asking students to browse the full syllabus.
UX support
I centered the page around Next Up, the current module, and resume learning, while keeping broader exploration available but secondary.
04
Decision aim
Turn low-score and return moments into clear recovery instead of self-diagnosis.
Product decision
When students underperform or return after a break, the LMS should generate a recovery path instead of leaving them to self-correct.
UX support
The recovery state should show what happened and surface a clear remedial or revision action, so students restart from motion, not confusion.
Together, these decisions made good learning behavior the default — not something left to willpower.
Shipped Flow
Below is a recreated interactive demo of the shipped flow, using mock data and content. It preserves the case-study experience even as the live product evolves.
You can also experience the product on the live platform by following the steps below.
Small caveat: The live product is actively maintained, so the current experience may differ from the archived flow shown in this case study.
Process: the engine behind the speed
DesignForge — my 6-phase AI + human methodology for shipping design and code together.
Not by brute force. Experience first, interface next, production last.
I had already seen the trap: when product logic, UX flow, UI polish, code, data, and production constraints are solved together, the work gets noisy.
So I split the build into layers: experience first, interface next, production last.
Each step produced evidence.
It moved one node at a time.
00
Input specification package
Before build, I wrote down all the business rules, screens, journeys, component behavior, wireframes, screen flow, backend contracts, and success criteria, so the feature had one source of truth.
What this prevented: AI inventing product logic mid-build.
--- ## 2. How Remedials Work ### The Core Flow ┌─────────────────────────────────────────────────────────────────────────┐ │ │ │ 1. COMPLETE ACTIVITY 2. MISTAKES DETECTED 3. REMEDIAL CREATED │ │ │ │ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │Process Skill│ ───▶ │ 3 wrong answers │ ───▶ │ 6-question │ │ │ │ (8 Qs) │ │ detected │ │ remedial added │ │ │ └─────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ │ Student scores System identifies Modal prompts │ │ 75% (below 80%) specific mistakes "Start Remedial" │ │ │ └─────────────────────────────────────────────────────────────────────────┘
---
## J1: Concept File Remedial (Happy Path)
**Trigger:** Student makes any mistake in a Concept File (100% required)
┌────────────────────────────────────────────────────────────────────────┐
│ STEP 1: Complete Concept File │
├────────────────────────────────────────────────────────────────────────┤
│ Student completes CF with 4/5 correct (80%) │
│ System detects: 1 mistake → triggers remedial │
└────────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────────┐
│ STEP 2: Activity Results Screen │
├────────────────────────────────────────────────────────────────────────┤
│ Shows: │
│ • Score: 80%--- ## 1. Data Models & Schema ### `remedials` Table CREATE TABLE remedials ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), student_id UUID NOT NULL REFERENCES students(id), course_id UUID NOT NULL REFERENCES courses(id), mother_activity_id UUID NOT NULL REFERENCES activities(id), -- Remedial metadata question_count INTEGER NOT NULL, time_estimate_minutes INTEGER NOT NULL, reason TEXT NOT NULL, -- "3 mistakes in Linear Equations Practice" -- Questions (references to parallel questions) question_ids UUID[] NOT NULL,
01
Journey component map
Once the specification — what we are trying to build — was written into an ironclad input, I converted that into a student journey and a component dependency map, so the feature could be judged as a flow instead of isolated screens.
What this prevented: Screens that looked right alone but failed in sequence.
Hover/Click on the component badges to understand what they are
| Journey | Component flow |
|---|---|
| CF Remedial (Happy Path)Trigger: Any mistake in Concept File (100% required) | Activity Complete:M1M1ModifiedActivity Results ScreenAdd space for R6 notice. Continue button triggers R1 modal if remedial created.StatesResults OnlyResults + Remedial Notice→R6R6Notice (New)Results Screen NoticeSection in activity results screen indicating remedial was created. Shows question count and time estimate.StatesVisible (remedial created)Hidden (no remedial)→R1R1Modal (New)Remedial Created ModalSingle-button prompt after activity with mistakes. Shows mistake count, question count, and time estimate. One button: "Start Remedial".StatesVisibleDismissed Remedial Quiz:R4R4Header (New)Remedial Activity HeaderHeader during remedial quiz showing context: "REMEDIAL" badge, mother activity name, mistake count, progress.StatesDefault→R3R3Feedback (New)Remedial Completion FeedbackScore-based messaging after remedial completion. Green checkmark for 100%, amber warning for <100%.StatesPerfect (100%)With Mistakes (<100%) Course Home:M2M2ModifiedCourse SidebarSupport indented remedial rows (R2). Remedials insert below mother activity with visual hierarchy.StatesDefaultWith Remedials→M3M3ModifiedNext Up SectionInclude remedials in queue. Priority: oldest pending remedial first (FIFO), then regular activities.StatesNo RemedialsWith Pending Remedials→M4M4ModifiedCourse Progress DisplayAccount for remedials: total = base - pace_shaded + remedials_created. Completed includes remedials.StatesDefault→M6M6ModifiedCourse Time EstimateInclude pending remedial time in remaining estimate. Updates when remedial created.StatesDefault |
| Process Skill RemedialTrigger: Score below 80% in Process Skill | Same as J1 (different trigger threshold: <80% instead of any mistake) |
| Remedial SkippedTrigger: User dismisses R1 modal | R1R1 (dismissed)Modal (New)Remedial Created ModalSingle-button prompt after activity with mistakes. Shows mistake count, question count, and time estimate. One button: "Start Remedial".StatesVisibleDismissed→M2M2 (pending)ModifiedCourse SidebarSupport indented remedial rows (R2). Remedials insert below mother activity with visual hierarchy.StatesDefaultWith Remedials Result:Remedial stays in sidebar (not_started), appears in Next Up. NOT blocking. |
02
Sandbox requirement doc
With the journey and component map in hand, I set up a sandbox where those components could be assembled, tested, broken, and improved away from production pressure.
What this prevented: Production constraints deciding the UX too early.
--- ## 8. Sandbox File Structure ``` pages/sandbox/remedials/ ├── PageHome.jsx # Copy, replace API with mock data ├── PageHome.css # Copy ├── ActivityPage.jsx # Copy, add remedial callback handling ├── ActivityPage.css # Copy ├── components/ │ ├── activity/ # Activity page components │ │ ├── ActivityPageShell.jsx │ │ ├── ActivityPageShell.css │ │ └── index.js │ ├── course/ # Course page components │ │ ├── ActivityLineItem.jsx │ │ ├── ActivityLineItem.css │ │ ├── UnitBlock.jsx │ │ ├── UnitBlock.css
## 9. Routing Setup Add to `App.jsx`: ``` // Course home sandbox <Route path="/sandbox/remedials/:courseCode" element={<RemedialsSandboxHome />} /> // Activity page sandbox <Route path="/sandbox/remedials/:courseCode/activity/:activityId" element= {<RemedialsSandboxActivity />} />
03
Rough working build + gap docs
Inside the sandbox, I used a rough working build to find missing states, unclear next actions, weak hierarchy, and backend gaps before any visual polish.
What this prevented: Polishing while core data contracts were still unclear.
### Q4: How do R6 Notice and R1 Modal integrate with Activity Results?
Affected Components: R6 (Notice), R1 (Modal), M1 (Results Screen)
The Issue:
Options:
| Option | Description |
|---|---|
| (A) ActivityPage wrapper | ActivityPage receives completion event, renders custom results wrapper with R6, then R1 modal |
| (B) Overlay approach | Let spark-maximus show default results, ActivityPage overlays R6/R1 on top |
| (C) Callback injection | Pass render callback to spark-maximus to inject R6 into its results |
### Fields Required in Remedial Children (for Next Up card display)
| Field | Type | Required | Description | Used For |
|---|---|---|---|---|
contentId | number | Yes | Unique ID of the remedial | Navigation |
contentType | string | Yes | Must be "REMEDIAL" | Card styling (red/coral theme) |
contentName | string | Yes | Display name (preferably "REM: [Activity Name]") | Card title |
correlationId | string | Yes | UUID for Neuron iframe | Launching remedial |
estimatedDurationMinutes | number | Yes | Expected completion time | Time badge on card |
progressStatus | string | Yes | "NOT_STARTED", "INPROGRESS", "COMPLETED" | Status badge |
questionCount | number | Needs verification | Number of questions | Card info display |
mistakeCount | number | Needs verification | Mistakes that triggered it | Description: "Fix X gaps..." |
motherActivityName | string | Needs verification | Parent activity name | Description: "...based on [name] attempt" |
How Frontend Uses This
04
Component renders + design specification
Once the rough build had exposed the real UX behavior, I moved into interface design — only then documenting hierarchy, states, and treatment.
What this prevented: Pretty UI detached from behavior.
Converted to React components for easier iteration.
Showing remedials within a complete unit listing with varying states.
Remedial with red accent until completion (both not-started and in-progress states).
Remedial row is positioned OUTSIDE the assessment yellow container.
Module mock completed, remedial not yet attempted (red accent).
Same component used twice: inside grade block (top) and standalone (before checklist).
At the concept level, even one mistake means there's a gap. This is fixable—but only if you fix it now.
Based on your 2 mistakes, we've prepared a targeted practice.
Based on your 2 mistakes, we've prepared a targeted practice.
05
Integrated sandbox
I dropped the polished components back into the sandbox and tested them as one complete flow, so the polish had to survive the journey end to end.
What this prevented: Polished components that did not survive the full flow.
Phase 4 - Sandbox Integration
Goal: Implement finalized designs using established patterns and design tokens.
By the end, the sandbox should have:
Integration rule:
Use production tokens, follow existing component patterns, document non-obvious behavior, and test components together, not in isolation.
06
Migration to production.
With the full flow validated, I moved to production with migration notes, system checks, backend contracts, and token-deviation reports, so intent did not get flattened in handoff.
What this prevented: Intent getting flattened in handoff.
## 3. New Components to Migrate
From Sandbox to Production
| Code | Component | Sandbox Location | Production Location |
|---|---|---|---|
R1 | RemedialCreatedModal | sandbox/remedials/components/remedials/RemedialCreatedModal/ | src/components/remedials/RemedialCreatedModal/ |
R3 | RemedialCompletionFeedback | sandbox/remedials/components/remedials/RemedialCompletionFeedback/ | src/components/remedials/RemedialCompletionFeedback/ |
R4 | RemedialActivityHeader | sandbox/remedials/components/remedials/RemedialActivityHeader/ | src/components/remedials/RemedialActivityHeader/ |
R5 | RemedialReasonTooltip | sandbox/remedials/components/remedials/RemedialReasonTooltip/ | src/components/remedials/RemedialReasonTooltip/ |
R6 | RemedialResultsNotice | sandbox/remedials/components/remedials/RemedialResultsNotice/ | src/components/remedials/RemedialResultsNotice/ |
Create New Folder Structure
src/components/remedials/ ├── RemedialCreatedModal/ │ ├── RemedialCreatedModal.jsx │ ├── RemedialCreatedModal.css │ └── index.js ├── RemedialCompletionFeedback/ ├── RemedialActivityHeader/ ├── RemedialReasonTooltip/ ├── RemedialResultsNotice/ └── index.js
## Overall Migration Order
Execute migrations in this sequence to avoid broken dependencies:
┌─────────────────────────────────────────────────────────────────────────────┐
│ OVERALL MIGRATION SEQUENCE │
└─────────────────────────────────────────────────────────────────────────────┘
STEP 1 STEP 2 STEP 3
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ DELETE OLD │───────▶│ ADD NEW │───────▶│ UPDATE │
│ COMPONENTS │ │ COMPONENTS │ │ MODIFIED │
│ (Sequential) │ │ (PARALLEL) │ │ COMPONENTS │
│ │ │ │ │ (Sequential) │
│ • Remove pre- │ │ ┌───────────┐ │ │ │
│ spec files │ │ │ Agent 1 │ │ │ • UnitBlock │
│ • Update │ │ │ Component │ │ │ • CurrentMod- │
│ index.js │ │ └───────────┘ │ │ uleCard │
│ • Remove │ │ ┌───────────┐ │ │ • Activity- │
│ imports │ │ │ Agent 2 │ │ │ LineItem │
│ │ │ │ Component │ │ │ • PageHome │
│ │ │ └───────────┘ │ │ • ActivityPage│
│ │ │ ┌───────────┐ │ │ │
│ │ │ │ Agent N │ │ │ Full diff │
│ │ │ │ Component │ │ │ approach │
│ │ │ └───────────┘ │ │ │
└───────────────┘ └───────────────┘ └───────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────────────────────────────────┐
│ STEP 4: VERIFY │
│ Run app, test all user journeys, check responsive, verify API │
└───────────────────────────────────────────────────────────────────┘## Component Audit Reports
R1: RemedialCreatedModal
Files: JSX and CSS implementation for RemedialCreatedModal
| Category | Status | Notes |
|---|---|---|
| Typography | ☐ Pass / ☐ Fail | |
| Colors | ☐ Pass / ☐ Fail | |
| Spacing | ☐ Pass / ☐ Fail | |
| Border Radius | ☐ Pass / ☐ Fail | |
| Shadows | ☐ Pass / ☐ Fail | |
| Responsive | ☐ Pass / ☐ Fail | |
| Accessibility | ☐ Pass / ☐ Fail | |
| Animations | ☐ Pass / ☐ Fail | |
| Component Structure | ☐ Pass / ☐ Fail | |
| Code Quality | ☐ Pass / ☐ Fail | |
| Icons Usage | ☐ Pass / ☐ Fail | Inline SVG arrow needs fix |
| Classname Semantics | ☐ Pass / ☐ Fail | r1- → remedial-created-modal- |
Input specification package
Before build, I wrote down all the business rules, screens, journeys, component behavior, wireframes, screen flow, backend contracts, and success criteria, so the feature had one source of truth.
What this prevented: AI inventing product logic mid-build.
--- ## 2. How Remedials Work ### The Core Flow ┌─────────────────────────────────────────────────────────────────────────┐ │ │ │ 1. COMPLETE ACTIVITY 2. MISTAKES DETECTED 3. REMEDIAL CREATED │ │ │ │ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ │ │Process Skill│ ───▶ │ 3 wrong answers │ ───▶ │ 6-question │ │ │ │ (8 Qs) │ │ detected │ │ remedial added │ │ │ └─────────────┘ └─────────────────┘ └─────────────────┘ │ │ │ │ Student scores System identifies Modal prompts │ │ 75% (below 80%) specific mistakes "Start Remedial" │ │ │ └─────────────────────────────────────────────────────────────────────────┘
---
## J1: Concept File Remedial (Happy Path)
**Trigger:** Student makes any mistake in a Concept File (100% required)
┌────────────────────────────────────────────────────────────────────────┐
│ STEP 1: Complete Concept File │
├────────────────────────────────────────────────────────────────────────┤
│ Student completes CF with 4/5 correct (80%) │
│ System detects: 1 mistake → triggers remedial │
└────────────────────────────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────────────┐
│ STEP 2: Activity Results Screen │
├────────────────────────────────────────────────────────────────────────┤
│ Shows: │
│ • Score: 80%--- ## 1. Data Models & Schema ### `remedials` Table CREATE TABLE remedials ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), student_id UUID NOT NULL REFERENCES students(id), course_id UUID NOT NULL REFERENCES courses(id), mother_activity_id UUID NOT NULL REFERENCES activities(id), -- Remedial metadata question_count INTEGER NOT NULL, time_estimate_minutes INTEGER NOT NULL, reason TEXT NOT NULL, -- "3 mistakes in Linear Equations Practice" -- Questions (references to parallel questions) question_ids UUID[] NOT NULL,
Journey component map
Once the specification — what we are trying to build — was written into an ironclad input, I converted that into a student journey and a component dependency map, so the feature could be judged as a flow instead of isolated screens.
What this prevented: Screens that looked right alone but failed in sequence.
Hover/Click on the component badges to understand what they are
| Journey | Component flow |
|---|---|
| CF Remedial (Happy Path)Trigger: Any mistake in Concept File (100% required) | Activity Complete:M1M1ModifiedActivity Results ScreenAdd space for R6 notice. Continue button triggers R1 modal if remedial created.StatesResults OnlyResults + Remedial Notice→R6R6Notice (New)Results Screen NoticeSection in activity results screen indicating remedial was created. Shows question count and time estimate.StatesVisible (remedial created)Hidden (no remedial)→R1R1Modal (New)Remedial Created ModalSingle-button prompt after activity with mistakes. Shows mistake count, question count, and time estimate. One button: "Start Remedial".StatesVisibleDismissed Remedial Quiz:R4R4Header (New)Remedial Activity HeaderHeader during remedial quiz showing context: "REMEDIAL" badge, mother activity name, mistake count, progress.StatesDefault→R3R3Feedback (New)Remedial Completion FeedbackScore-based messaging after remedial completion. Green checkmark for 100%, amber warning for <100%.StatesPerfect (100%)With Mistakes (<100%) Course Home:M2M2ModifiedCourse SidebarSupport indented remedial rows (R2). Remedials insert below mother activity with visual hierarchy.StatesDefaultWith Remedials→M3M3ModifiedNext Up SectionInclude remedials in queue. Priority: oldest pending remedial first (FIFO), then regular activities.StatesNo RemedialsWith Pending Remedials→M4M4ModifiedCourse Progress DisplayAccount for remedials: total = base - pace_shaded + remedials_created. Completed includes remedials.StatesDefault→M6M6ModifiedCourse Time EstimateInclude pending remedial time in remaining estimate. Updates when remedial created.StatesDefault |
| Process Skill RemedialTrigger: Score below 80% in Process Skill | Same as J1 (different trigger threshold: <80% instead of any mistake) |
| Remedial SkippedTrigger: User dismisses R1 modal | R1R1 (dismissed)Modal (New)Remedial Created ModalSingle-button prompt after activity with mistakes. Shows mistake count, question count, and time estimate. One button: "Start Remedial".StatesVisibleDismissed→M2M2 (pending)ModifiedCourse SidebarSupport indented remedial rows (R2). Remedials insert below mother activity with visual hierarchy.StatesDefaultWith Remedials Result:Remedial stays in sidebar (not_started), appears in Next Up. NOT blocking. |
Sandbox requirement doc
With the journey and component map in hand, I set up a sandbox where those components could be assembled, tested, broken, and improved away from production pressure.
What this prevented: Production constraints deciding the UX too early.
--- ## 8. Sandbox File Structure ``` pages/sandbox/remedials/ ├── PageHome.jsx # Copy, replace API with mock data ├── PageHome.css # Copy ├── ActivityPage.jsx # Copy, add remedial callback handling ├── ActivityPage.css # Copy ├── components/ │ ├── activity/ # Activity page components │ │ ├── ActivityPageShell.jsx │ │ ├── ActivityPageShell.css │ │ └── index.js │ ├── course/ # Course page components │ │ ├── ActivityLineItem.jsx │ │ ├── ActivityLineItem.css │ │ ├── UnitBlock.jsx │ │ ├── UnitBlock.css
## 9. Routing Setup Add to `App.jsx`: ``` // Course home sandbox <Route path="/sandbox/remedials/:courseCode" element={<RemedialsSandboxHome />} /> // Activity page sandbox <Route path="/sandbox/remedials/:courseCode/activity/:activityId" element= {<RemedialsSandboxActivity />} />
Rough working build + gap docs
Inside the sandbox, I used a rough working build to find missing states, unclear next actions, weak hierarchy, and backend gaps before any visual polish.
What this prevented: Polishing while core data contracts were still unclear.
### Q4: How do R6 Notice and R1 Modal integrate with Activity Results?
Affected Components: R6 (Notice), R1 (Modal), M1 (Results Screen)
The Issue:
Options:
| Option | Description |
|---|---|
| (A) ActivityPage wrapper | ActivityPage receives completion event, renders custom results wrapper with R6, then R1 modal |
| (B) Overlay approach | Let spark-maximus show default results, ActivityPage overlays R6/R1 on top |
| (C) Callback injection | Pass render callback to spark-maximus to inject R6 into its results |
### Fields Required in Remedial Children (for Next Up card display)
| Field | Type | Required | Description | Used For |
|---|---|---|---|---|
contentId | number | Yes | Unique ID of the remedial | Navigation |
contentType | string | Yes | Must be "REMEDIAL" | Card styling (red/coral theme) |
contentName | string | Yes | Display name (preferably "REM: [Activity Name]") | Card title |
correlationId | string | Yes | UUID for Neuron iframe | Launching remedial |
estimatedDurationMinutes | number | Yes | Expected completion time | Time badge on card |
progressStatus | string | Yes | "NOT_STARTED", "INPROGRESS", "COMPLETED" | Status badge |
questionCount | number | Needs verification | Number of questions | Card info display |
mistakeCount | number | Needs verification | Mistakes that triggered it | Description: "Fix X gaps..." |
motherActivityName | string | Needs verification | Parent activity name | Description: "...based on [name] attempt" |
How Frontend Uses This
Component renders + design specification
Once the rough build had exposed the real UX behavior, I moved into interface design — only then documenting hierarchy, states, and treatment.
What this prevented: Pretty UI detached from behavior.
Converted to React components for easier iteration.
Showing remedials within a complete unit listing with varying states.
Remedial with red accent until completion (both not-started and in-progress states).
Remedial row is positioned OUTSIDE the assessment yellow container.
Module mock completed, remedial not yet attempted (red accent).
Same component used twice: inside grade block (top) and standalone (before checklist).
At the concept level, even one mistake means there's a gap. This is fixable—but only if you fix it now.
Based on your 2 mistakes, we've prepared a targeted practice.
Based on your 2 mistakes, we've prepared a targeted practice.
Integrated sandbox
I dropped the polished components back into the sandbox and tested them as one complete flow, so the polish had to survive the journey end to end.
What this prevented: Polished components that did not survive the full flow.
Phase 4 - Sandbox Integration
Goal: Implement finalized designs using established patterns and design tokens.
By the end, the sandbox should have:
Integration rule:
Use production tokens, follow existing component patterns, document non-obvious behavior, and test components together, not in isolation.
Migration to production.
With the full flow validated, I moved to production with migration notes, system checks, backend contracts, and token-deviation reports, so intent did not get flattened in handoff.
What this prevented: Intent getting flattened in handoff.
## 3. New Components to Migrate
From Sandbox to Production
| Code | Component | Sandbox Location | Production Location |
|---|---|---|---|
R1 | RemedialCreatedModal | sandbox/remedials/components/remedials/RemedialCreatedModal/ | src/components/remedials/RemedialCreatedModal/ |
R3 | RemedialCompletionFeedback | sandbox/remedials/components/remedials/RemedialCompletionFeedback/ | src/components/remedials/RemedialCompletionFeedback/ |
R4 | RemedialActivityHeader | sandbox/remedials/components/remedials/RemedialActivityHeader/ | src/components/remedials/RemedialActivityHeader/ |
R5 | RemedialReasonTooltip | sandbox/remedials/components/remedials/RemedialReasonTooltip/ | src/components/remedials/RemedialReasonTooltip/ |
R6 | RemedialResultsNotice | sandbox/remedials/components/remedials/RemedialResultsNotice/ | src/components/remedials/RemedialResultsNotice/ |
Create New Folder Structure
src/components/remedials/ ├── RemedialCreatedModal/ │ ├── RemedialCreatedModal.jsx │ ├── RemedialCreatedModal.css │ └── index.js ├── RemedialCompletionFeedback/ ├── RemedialActivityHeader/ ├── RemedialReasonTooltip/ ├── RemedialResultsNotice/ └── index.js
## Overall Migration Order
Execute migrations in this sequence to avoid broken dependencies:
┌─────────────────────────────────────────────────────────────────────────────┐
│ OVERALL MIGRATION SEQUENCE │
└─────────────────────────────────────────────────────────────────────────────┘
STEP 1 STEP 2 STEP 3
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ DELETE OLD │───────▶│ ADD NEW │───────▶│ UPDATE │
│ COMPONENTS │ │ COMPONENTS │ │ MODIFIED │
│ (Sequential) │ │ (PARALLEL) │ │ COMPONENTS │
│ │ │ │ │ (Sequential) │
│ • Remove pre- │ │ ┌───────────┐ │ │ │
│ spec files │ │ │ Agent 1 │ │ │ • UnitBlock │
│ • Update │ │ │ Component │ │ │ • CurrentMod- │
│ index.js │ │ └───────────┘ │ │ uleCard │
│ • Remove │ │ ┌───────────┐ │ │ • Activity- │
│ imports │ │ │ Agent 2 │ │ │ LineItem │
│ │ │ │ Component │ │ │ • PageHome │
│ │ │ └───────────┘ │ │ • ActivityPage│
│ │ │ ┌───────────┐ │ │ │
│ │ │ │ Agent N │ │ │ Full diff │
│ │ │ │ Component │ │ │ approach │
│ │ │ └───────────┘ │ │ │
└───────────────┘ └───────────────┘ └───────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────────────────────────────────┐
│ STEP 4: VERIFY │
│ Run app, test all user journeys, check responsive, verify API │
└───────────────────────────────────────────────────────────────────┘## Component Audit Reports
R1: RemedialCreatedModal
Files: JSX and CSS implementation for RemedialCreatedModal
| Category | Status | Notes |
|---|---|---|
| Typography | ☐ Pass / ☐ Fail | |
| Colors | ☐ Pass / ☐ Fail | |
| Spacing | ☐ Pass / ☐ Fail | |
| Border Radius | ☐ Pass / ☐ Fail | |
| Shadows | ☐ Pass / ☐ Fail | |
| Responsive | ☐ Pass / ☐ Fail | |
| Accessibility | ☐ Pass / ☐ Fail | |
| Animations | ☐ Pass / ☐ Fail | |
| Component Structure | ☐ Pass / ☐ Fail | |
| Code Quality | ☐ Pass / ☐ Fail | |
| Icons Usage | ☐ Pass / ☐ Fail | Inline SVG arrow needs fix |
| Classname Semantics | ☐ Pass / ☐ Fail | r1- → remedial-created-modal- |
Less rework because the product was not being rediscovered during execution.
Building the rough experience first exposed UX problems before visual polish.
Every component had a known role inside the student journey.
The final feature carried product logic and design intent into the real system.
Why this worked?
The spec carried the logic.
The journey carried the flow.
The rough build exposed the UX.
The interface sharpened the product.
Outcome
Students started faster, continued more often, and completed more of what the system recommended.
89%
Next-step continuation?Measures how often students start the next recommended activity immediately after completing one.This improved by making the next step explicit, removing alternate paths, and keeping the user in a continuous flow instead of returning them to a menu.
up from 32%
72%
Progress depth?Measures how much of the system-recommended path a student completes before dropping off.This increased by structuring the course into guided, adaptive paths, ensuring students only see what they need and do not get lost in the full syllabus.
up from 52%
45 sec
Time to first meaningful action?Measures how long it takes for a student to start their first learning activity after opening the app.Reduced by removing setup decisions and surfacing a single, immediate next action, so users can start learning without figuring out where to begin.
down from 1 min 52 sec
SanchariTechnical Lead, e-GMAT"I had not thought about UX at this level before. The minute decisions Lohith made made the flow surprisingly easy to follow. What also stood out was how he used DesignForge to break the work into simple atomic blocks, which sped development up very quickly."
AbhishekBackend Developer, e-GMAT"Lohith was very clear about frontend data requirements, which made the backend contracts easy to draft. Within a week, even though he is not a developer, he picked up the language and methods fast, and that made collaboration smoother with very little rework."
That is how I built this one.