SAT LMS

The LMS that personalizes your learning so that you learn only what you need to.

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.

Principal Product Designer & Frontend DeveloperDec 2025 - Mar 2026e-gmat.com logoe-gmat.com

Logos are properties of their respective companies.

TL;DR

Learning management system transforms confused SAT learners into clear and confident students

My Impact

After my redesign, the LMS showed a clear shift in learning behavior: faster starts, deeper progression, and significantly higher continuation rates.

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

My approach

How I approached the problem

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?

EVALUATE

They would first understand where the student currently stands.

GUIDE

A tutor would channel effort toward what needs to be learned next, instead of making the student learn everything.

ENCOURAGE

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

I made the diagnostic the first evident action.

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

I made the personalized path feel earned — not magical.

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

I made the next action dominant and pushed exploration into the background.

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

I turned weak moments into guided re-entry points.

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

I made the diagnostic the first evident action.

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

I made the personalized path feel earned — not magical.

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

I made the next action dominant and pushed exploration into the background.

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

I turned weak moments into guided re-entry points.

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

Experience it yourself!

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.

DESIGN

Product Design Foundations

0% complete
Focus

Personalize Your Path

Take a quick diagnostic to discover what you already know. Students typically save up to 70% of study time.

10 min5 questionsOne-time assessment
Next UpYour immediate next steps in this course

Personalize Your Path

Diagnostic
1

User Problems vs Business Goals

Concept
2

Framing Problem Statements

Concept
3

Defining Outcome Metrics

Concept
4

Interview Note Synthesis

Process Skill
5

Writing Interview Guides

Concept
Your First Module
Start your course with this module
1
Module 1: Problem Framing and Research
5h 35min
0/7
Unit 1.1
Framing Product Problems·3h 30min
0/4
1.1.1
User Problems vs Business Goals·1h1h
1.1.2
Framing Problem Statements·55 min55 min
1.1.3
Defining Outcome Metrics·50 min50 min
1.1.4
Interview Note Synthesis·45 min45 min
Unit 1.2
Discovery Interviews·1h 35min
0/2
1.2.1
Writing Interview Guides·55 min55 min
1.2.2
Spotting Repeated Themes·40 min40 min
Assessment
Module 1 Mock·30 min
Unattempted
Focus

Try the current live product

You can also experience the product on the live platform by following the steps below.

1 Create a free account2 Open the course3 Start the diagnostic
i

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

Built with DesignForge in four weeks

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.

The product did not jump from idea to UI.

It moved one node at a time.

00

Input specification package

Talk it through before walking it

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.

01-context-and-business-rules-remedials.md
---
## 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"    │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘
03-user-journey-map-remedials.md
---
## 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%
07-backend-specification-remedials.md
---
## 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

Map the behavior

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.

Journey component mapping | Remedials

Hover/Click on the component badges to understand what they are

JourneyComponent 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 NoticeR6R6Notice (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.StatesDefaultR3R3Feedback (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 RemedialsM3M3ModifiedNext Up SectionInclude remedials in queue. Priority: oldest pending remedial first (FIFO), then regular activities.StatesNo RemedialsWith Pending RemedialsM4M4ModifiedCourse Progress DisplayAccount for remedials: total = base - pace_shaded + remedials_created. Completed includes remedials.StatesDefaultM6M6ModifiedCourse 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".StatesVisibleDismissedM2M2 (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

Create a safe build space

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.

02-sandbox-requirement-remedials.md
---
## 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

Make the experience work before making it beautiful

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.

gap-analysis-summary-remedials.md

### Q4: How do R6 Notice and R1 Modal integrate with Activity Results?

Affected Components: R6 (Notice), R1 (Modal), M1 (Results Screen)

The Issue:

  • Spec shows R6 as a section within the results screen
  • R1 modal appears after clicking "Continue" on results
  • O0 decision says ActivityPage handles this via callback

Options:

OptionDescription
(A) ActivityPage wrapperActivityPage receives completion event, renders custom results wrapper with R6, then R1 modal
(B) Overlay approachLet spark-maximus show default results, ActivityPage overlays R6/R1 on top
(C) Callback injectionPass render callback to spark-maximus to inject R6 into its results
backend-gap-analysis-remedials.md

### Fields Required in Remedial Children (for Next Up card display)

FieldTypeRequiredDescriptionUsed For
contentIdnumberYesUnique ID of the remedialNavigation
contentTypestringYesMust be "REMEDIAL"Card styling (red/coral theme)
contentNamestringYesDisplay name (preferably "REM: [Activity Name]")Card title
correlationIdstringYesUUID for Neuron iframeLaunching remedial
estimatedDurationMinutesnumberYesExpected completion timeTime badge on card
progressStatusstringYes"NOT_STARTED", "INPROGRESS", "COMPLETED"Status badge
questionCountnumberNeeds verificationNumber of questionsCard info display
mistakeCountnumberNeeds verificationMistakes that triggered itDescription: "Fix X gaps..."
motherActivityNamestringNeeds verificationParent activity nameDescription: "...based on [name] attempt"

How Frontend Uses This

  1. Extract remedials from `activity.children` in the Next Up block
  2. Flatten them into the `contentItems` array
  3. Render each remedial as a separate card immediately after its parent activity

04

Component renders + design specification

Forge the interface

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.

Expanded State

Collapsed State

R2: Remedial Activity Row - React Version

Converted to React components for easier iteration.

1. Full Unit Context - Multiple Activities with Remedials

Showing remedials within a complete unit listing with varying states.

Unit 1.1
Introduction to Algebra·
45 min
3/5
1.1.1
Understanding Variables·
10 min
95%
08:32
1.1.2
Algebraic Expressions·
15 min
70%
12:18
REM.
Algebraic Expressions·
6 Qs
·
12 min
1.1.3
Practice: Solving Equations·
20 min
75%
16:42
REM.
Practice: Solving Equations·
4 Qs
·
8 min
100%
06:18
1.1.4
Word Problems in Algebra·
15 min
2. Remedial In Progress (Red Theme)

Remedial with red accent until completion (both not-started and in-progress states).

2.1.1
Quadratic Equations Practice·
25 min
68%
22:15
REM.
Quadratic Equations Practice·
8 Qs
·
16 min
04:22
3. Module Mock → Remedial (Outside Yellow Block)

Remedial row is positioned OUTSIDE the assessment yellow container.

Assessment
Module 2 Mock Test·
45 min
65%
Attempted
REM.
Module 2 Mock Test·
8 Qs
·
16 min
50%
14:28
4. Module Mock → Remedial (Not Started)

Module mock completed, remedial not yet attempted (red accent).

Assessment
Module 3 Mock Test·
60 min
72%
Attempted
REM.
Module 3 Mock Test·
6 Qs
·
12 min
R2 State Reference
R2-S1: Not Started
Red accent, red badge
R2-S2: In Progress
Red accent, red badge
R2-S3: Completed (Pass)
No accent, grey badge, 100%
R2-S4: Completed (Fail)
No accent, grey badge, <100%

R6: Remedial Notice — Dual Placement

Same component used twice: inside grade block (top) and standalone (before checklist).

PLACEMENT 1
GRADEC
67% correct. Still in the bottom 50%.

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.

REM.Linear Equations Practice
4 Qs8 min
bottom 50%

Question Breakdown

[ Content Area ]

Your Time Progression

[ Content Area ]
PLACEMENT 2

Fix your gaps before you move forward

Based on your 2 mistakes, we've prepared a targeted practice.

REM.Linear Equations Practice
4 Qs8 min

Before You Move On

05

Integrated sandbox

Assemble the experience

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.

PR4 - Sandbox Integration.md

Phase 4 - Sandbox Integration

Goal: Implement finalized designs using established patterns and design tokens.

By the end, the sandbox should have:

  1. All components built with proper design tokens and patterns
  2. Full responsive implementation across mobile, tablet, and desktop
  3. Components integrated and working together in the sandbox
  4. A migration map documenting what needs to move to production

Integration rule:

Use production tokens, follow existing component patterns, document non-obvious behavior, and test components together, not in isolation.

Sandbox integration
Sandbox integration/|-- Task P3.1 - R2 integration.md|-- Task P3.2 - M2 UI update.md`-- Task P3.2 - R6 integration.md

06

Migration to production.

Move into 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.

prod-migration-map.md

## 3. New Components to Migrate

From Sandbox to Production

CodeComponentSandbox LocationProduction Location
R1RemedialCreatedModalsandbox/remedials/components/remedials/RemedialCreatedModal/src/components/remedials/RemedialCreatedModal/
R3RemedialCompletionFeedbacksandbox/remedials/components/remedials/RemedialCompletionFeedback/src/components/remedials/RemedialCompletionFeedback/
R4RemedialActivityHeadersandbox/remedials/components/remedials/RemedialActivityHeader/src/components/remedials/RemedialActivityHeader/
R5RemedialReasonTooltipsandbox/remedials/components/remedials/RemedialReasonTooltip/src/components/remedials/RemedialReasonTooltip/
R6RemedialResultsNoticesandbox/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
migration-process-flowchart

## 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    │
└───────────────────────────────────────────────────────────────────┘
Front-End Audit

## Component Audit Reports

R1: RemedialCreatedModal

Files: JSX and CSS implementation for RemedialCreatedModal

CategoryStatusNotes
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 / ☐ FailInline SVG arrow needs fix
Classname Semantics☐ Pass / ☐ Failr1- → remedial-created-modal-

Input specification package

Talk it through before walking it

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.

01-context-and-business-rules-remedials.md
---
## 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"    │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘
03-user-journey-map-remedials.md
---
## 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%
07-backend-specification-remedials.md
---
## 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

Map the behavior

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.

Journey component mapping | Remedials

Hover/Click on the component badges to understand what they are

JourneyComponent 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 NoticeR6R6Notice (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.StatesDefaultR3R3Feedback (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 RemedialsM3M3ModifiedNext Up SectionInclude remedials in queue. Priority: oldest pending remedial first (FIFO), then regular activities.StatesNo RemedialsWith Pending RemedialsM4M4ModifiedCourse Progress DisplayAccount for remedials: total = base - pace_shaded + remedials_created. Completed includes remedials.StatesDefaultM6M6ModifiedCourse 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".StatesVisibleDismissedM2M2 (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

Create a safe build space

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.

02-sandbox-requirement-remedials.md
---
## 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

Make the experience work before making it beautiful

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.

gap-analysis-summary-remedials.md

### Q4: How do R6 Notice and R1 Modal integrate with Activity Results?

Affected Components: R6 (Notice), R1 (Modal), M1 (Results Screen)

The Issue:

  • Spec shows R6 as a section within the results screen
  • R1 modal appears after clicking "Continue" on results
  • O0 decision says ActivityPage handles this via callback

Options:

OptionDescription
(A) ActivityPage wrapperActivityPage receives completion event, renders custom results wrapper with R6, then R1 modal
(B) Overlay approachLet spark-maximus show default results, ActivityPage overlays R6/R1 on top
(C) Callback injectionPass render callback to spark-maximus to inject R6 into its results
backend-gap-analysis-remedials.md

### Fields Required in Remedial Children (for Next Up card display)

FieldTypeRequiredDescriptionUsed For
contentIdnumberYesUnique ID of the remedialNavigation
contentTypestringYesMust be "REMEDIAL"Card styling (red/coral theme)
contentNamestringYesDisplay name (preferably "REM: [Activity Name]")Card title
correlationIdstringYesUUID for Neuron iframeLaunching remedial
estimatedDurationMinutesnumberYesExpected completion timeTime badge on card
progressStatusstringYes"NOT_STARTED", "INPROGRESS", "COMPLETED"Status badge
questionCountnumberNeeds verificationNumber of questionsCard info display
mistakeCountnumberNeeds verificationMistakes that triggered itDescription: "Fix X gaps..."
motherActivityNamestringNeeds verificationParent activity nameDescription: "...based on [name] attempt"

How Frontend Uses This

  1. Extract remedials from `activity.children` in the Next Up block
  2. Flatten them into the `contentItems` array
  3. Render each remedial as a separate card immediately after its parent activity

Component renders + design specification

Forge the interface

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.

Expanded State

Collapsed State

R2: Remedial Activity Row - React Version

Converted to React components for easier iteration.

1. Full Unit Context - Multiple Activities with Remedials

Showing remedials within a complete unit listing with varying states.

Unit 1.1
Introduction to Algebra·
45 min
3/5
1.1.1
Understanding Variables·
10 min
95%
08:32
1.1.2
Algebraic Expressions·
15 min
70%
12:18
REM.
Algebraic Expressions·
6 Qs
·
12 min
1.1.3
Practice: Solving Equations·
20 min
75%
16:42
REM.
Practice: Solving Equations·
4 Qs
·
8 min
100%
06:18
1.1.4
Word Problems in Algebra·
15 min
2. Remedial In Progress (Red Theme)

Remedial with red accent until completion (both not-started and in-progress states).

2.1.1
Quadratic Equations Practice·
25 min
68%
22:15
REM.
Quadratic Equations Practice·
8 Qs
·
16 min
04:22
3. Module Mock → Remedial (Outside Yellow Block)

Remedial row is positioned OUTSIDE the assessment yellow container.

Assessment
Module 2 Mock Test·
45 min
65%
Attempted
REM.
Module 2 Mock Test·
8 Qs
·
16 min
50%
14:28
4. Module Mock → Remedial (Not Started)

Module mock completed, remedial not yet attempted (red accent).

Assessment
Module 3 Mock Test·
60 min
72%
Attempted
REM.
Module 3 Mock Test·
6 Qs
·
12 min
R2 State Reference
R2-S1: Not Started
Red accent, red badge
R2-S2: In Progress
Red accent, red badge
R2-S3: Completed (Pass)
No accent, grey badge, 100%
R2-S4: Completed (Fail)
No accent, grey badge, <100%

R6: Remedial Notice — Dual Placement

Same component used twice: inside grade block (top) and standalone (before checklist).

PLACEMENT 1
GRADEC
67% correct. Still in the bottom 50%.

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.

REM.Linear Equations Practice
4 Qs8 min
bottom 50%

Question Breakdown

[ Content Area ]

Your Time Progression

[ Content Area ]
PLACEMENT 2

Fix your gaps before you move forward

Based on your 2 mistakes, we've prepared a targeted practice.

REM.Linear Equations Practice
4 Qs8 min

Before You Move On

Integrated sandbox

Assemble the experience

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.

PR4 - Sandbox Integration.md

Phase 4 - Sandbox Integration

Goal: Implement finalized designs using established patterns and design tokens.

By the end, the sandbox should have:

  1. All components built with proper design tokens and patterns
  2. Full responsive implementation across mobile, tablet, and desktop
  3. Components integrated and working together in the sandbox
  4. A migration map documenting what needs to move to production

Integration rule:

Use production tokens, follow existing component patterns, document non-obvious behavior, and test components together, not in isolation.

Sandbox integration
Sandbox integration/|-- Task P3.1 - R2 integration.md|-- Task P3.2 - M2 UI update.md`-- Task P3.2 - R6 integration.md

Migration to production.

Move into 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.

prod-migration-map.md

## 3. New Components to Migrate

From Sandbox to Production

CodeComponentSandbox LocationProduction Location
R1RemedialCreatedModalsandbox/remedials/components/remedials/RemedialCreatedModal/src/components/remedials/RemedialCreatedModal/
R3RemedialCompletionFeedbacksandbox/remedials/components/remedials/RemedialCompletionFeedback/src/components/remedials/RemedialCompletionFeedback/
R4RemedialActivityHeadersandbox/remedials/components/remedials/RemedialActivityHeader/src/components/remedials/RemedialActivityHeader/
R5RemedialReasonTooltipsandbox/remedials/components/remedials/RemedialReasonTooltip/src/components/remedials/RemedialReasonTooltip/
R6RemedialResultsNoticesandbox/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
migration-process-flowchart

## 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    │
└───────────────────────────────────────────────────────────────────┘
Front-End Audit

## Component Audit Reports

R1: RemedialCreatedModal

Files: JSX and CSS implementation for RemedialCreatedModal

CategoryStatusNotes
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 / ☐ FailInline SVG arrow needs fix
Classname Semantics☐ Pass / ☐ Failr1- → remedial-created-modal-

The result?

Faster build

Less rework because the product was not being rediscovered during execution.

Cleaner UX

Building the rough experience first exposed UX problems before visual polish.

Better UI output

Every component had a known role inside the student journey.

Safer production migration

The final feature carried product logic and design intent into the real system.

Why this worked?

This build moved fast because AI was never solving the whole product at once.

  • The spec carried the logic.

  • The journey carried the flow.

  • The rough build exposed the UX.

  • The interface sharpened the product.

Each step narrowed the next one.

Outcome

The prescribed path changed student movement.

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

Sanchari portraitSanchariTechnical 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."

Abhishek portraitAbhishekBackend 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."