# STU-01 through STU-19: Figma Student Portal Production Specs

---

## STU-01: STUDENT DASHBOARD

### Frame: `RP/Student/STU-01-Dashboard`

**Canvas sizes:** Desktop (1440), Tablet (768), Mobile (375) × Light + Dark

---

### Desktop Light (1440px)

```
Frame: STU-01-Dashboard-Desktop-Light
Width: 1440px, Height: auto
BG: color/background

├── RP/Sidebar (role: student, state: expanded, active: dashboard)
│   Width: 260px, Height: 100vh
│
├── RP/Topbar (role: student)
│   Height: 64px
│   Page title: "Student Portal"
│
├── Content Area
│   Left margin: 260px (sidebar width)
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── HERO SECTION
│   │   RP/Card (shadow/md, padding/lg, border)
│   │   Width: 100%, Height: 280px
│   │   BG: color/surface
│   │   Border-radius: 16px
│   │   Layout: Horizontal, gap 32px, alignment: center
│   │   Padding: 32px
│   │
│   │   ├── LEFT: OPS Ring
│   │   │   Layout: Vertical, gap 8px, alignment center
│   │   │   Width: 240px
│   │   │
│   │   │   ├── RP/OPSRing (size: xl, color-zone: green)
│   │   │   │   Diameter: 180px
│   │   │   │   Score: "78%"
│   │   │   │
│   │   │   └── "OPS Score" label
│   │   │       Font: Label/Base (14px, Medium)
│   │   │       Color: color/muted-text
│   │   │
│   │   ├── CENTER: Stats
│   │   │   Layout: Vertical, gap 16px
│   │   │   Flex: 1
│   │   │
│   │   │   ├── Rank Display
│   │   │   │   Layout: Horizontal, gap 8px, alignment: baseline
│   │   │   │   ├── "Class Rank:" (Body/SM, color/muted-text)
│   │   │   │   ├── "#5" (Display/H2, 30px, Bold, color/header-text)
│   │   │   │   ├── "of 40" (Body/Base, color/muted-text)
│   │   │   │   └── Trend arrow ↑ (color/success, +2 from last term)
│   │   │   │
│   │   │   ├── Streak (RP/StreakBadge, lg)
│   │   │   │   🔥 12 days
│   │   │   │   Subtext: "Longest: 18 days" (Body/XS, muted)
│   │   │   │
│   │   │   └── Tier (RP/TierBadge, tier: silver, highlighted)
│   │   │       "Silver" badge
│   │   │       Subtext: "250 pts to Gold" (Body/XS, muted)
│   │   │       Progress bar: 250/1500 (16.7%)
│   │   │
│   │   └── RIGHT: Quick Stats
│   │       Layout: Vertical, gap 12px
│   │       Width: 200px
│   │
│   │       ├── Stat Row: "Attendance" → "92%" (color/success)
│   │       ├── Stat Row: "Assignments" → "3 pending"
│   │       ├── Stat Row: "Exams" → "1 upcoming"
│   │       └── Stat Row: "Badges" → "8 earned"
│   │
│   ├── SUBJECT CARDS
│   │   Layout: Horizontal, gap 16px, scrollable on overflow
│   │   Width: 100%
│   │
│   │   Each card: RP/Card (shadow/sm, padding/md, border)
│   │   Width: 280px, Height: 140px
│   │   Layout: Vertical, gap 12px, padding 16px
│   │   Border-left: 4px {subject-color}
│   │
│   │   ├── Subject Name (Display/H6, 16px, Medium)
│   │   ├── Score Row (Horizontal, justify: space-between)
│   │   │   ├── Score: "85%" (KPI/Value, 30px, Bold)
│   │   │   │   Color: green (>80%), amber (60-79%), red (<60%)
│   │   │   └── Trend arrow: ↑ or ↓ (color/success or danger)
│   │   ├── Last grade: "A" (RP/Badge, type: success)
│   │   └── Mini sparkline (ApexCharts, 60×24px, area chart)
│   │
│   │   Card count: 1 per enrolled subject (4-6 typical)
│   │
│   ├── WIDGETS ROW
│   │   Layout: Horizontal, gap 16px
│   │
│   │   ├── WIDGET 1: Upcoming Deadlines (width: 50%)
│   │   │   RP/Card (shadow/sm, padding/md)
│   │   │   Height: 320px
│   │   │   Layout: Vertical, gap 0
│   │   │
│   │   │   ├── Header (Horizontal, justify: space-between)
│   │   │   │   ├── H5: "Upcoming Deadlines"
│   │   │   │   └── RP/Button (ghost, sm): "View All"
│   │   │   │
│   │   │   ├── Divider
│   │   │   │
│   │   │   └── Deadline List (Vertical, gap 0)
│   │   │       Each item:
│   │   │       ├── Height: 56px
│   │   │       ├── Padding: 12px 0
│   │   │       ├── Border-bottom: 1px color/divider
│   │   │       ├── Layout: Horizontal, gap 12px, alignment: center
│   │   │       │
│   │   │       ├── Type icon (20px)
│   │   │       │   📋 for assignment, 📝 for exam
│   │   │       │
│   │   │       ├── Info (flex: 1)
│   │   │       │   ├── Title: "Math Quiz Ch.5" (Body/SM, Medium)
│   │   │       │   └── Subject: "Mathematics" (Body/XS, muted)
│   │   │       │
│   │   │       └── Due badge
│   │   │           "Due tomorrow" → RP/Badge (danger, sm)
│   │   │           "Due in 3 days" → RP/Badge (warning, sm)
│   │   │           "Due in X days" → RP/Badge (neutral, sm)
│   │   │
│   │   │       Max 5 items shown
│   │   │       Empty state: RP/EmptyState (no CTA)
│   │   │
│   │   └── WIDGET 2: Recent Badges (width: 25%)
│   │       RP/Card (shadow/sm, padding/md)
│   │       Height: 320px
│   │       Layout: Vertical, gap 12px
│   │
│   │       ├── Header
│   │       │   ├── H5: "Recent Badges"
│   │       │   └── RP/Button (ghost, sm): "View All"
│   │       │
│   │       └── Badge Grid (2 columns, gap 12px)
│   │           Each badge:
│   │           ├── Badge icon (48px, circular)
│   │           │   BG: gamification/gold-bg
│   │           │   Icon: 🏆 (24px)
│   │           ├── Name (Body/XS, Medium)
│   │           └── Date (Body/XS, muted): "2 days ago"
│   │
│   │           Show last 3 badges
│   │           Locked: Greyscale + lock overlay
│   │
│   │   └── WIDGET 3: Leaderboard Position (width: 25%)
│       RP/Card (shadow/sm, padding/md)
│       Height: 320px
│       Layout: Vertical, gap 0
│
│       ├── Header
│       │   ├── H5: "Leaderboard"
│       │   └── RP/Button (ghost, sm): "Full Board"
│       │
│       ├── Tabs (RP/Tabs, variant: pill)
│       │   [Class] [School]
│       │
│       └── Leaderboard (Vertical, gap 0)
│           Each row:
│           ├── Height: 44px
│           ├── Padding: 0 12px
│           ├── Layout: Horizontal, gap 8px, alignment: center
│           │
│           ├── Rank: "🥇" / "🥈" / "🥉" / "4" / "5" (16px)
│           ├── Name: "Amara A." (Body/SM, flex: 1)
│           ├── OPS: "78%" (Body/SM, Bold)
│           └── Tier icon: 🥈 (14px)
│
│           Current student row: BG rgba(30,95,168,0.08)
│           Top 3: Medal icons
│
│           Show top 3 + current student
│           Separator line between top 3 and rest
│
└── Bottom padding: 48px
```

### Mobile Light (375px)

```
Frame: STU-01-Dashboard-Mobile-Light
Width: 375px, Height: auto
BG: color/background

├── RP/Topbar (mobile, height: 56px)
│
├── Content Area
│   Padding: 16px
│   Layout: Vertical, gap 16px
│
│   ├── Hero Section (RP/Card)
│   │   Width: 100%, Height: auto
│   │   Layout: Vertical, gap 16px, alignment: center, padding: 24px
│   │
│   │   ├── RP/OPSRing (size: lg, 120px)
│   │   ├── Stats row (Horizontal, gap 16px)
│   │   │   ├── Rank: "#5/40"
│   │   │   ├── Streak: RP/StreakBadge (sm)
│   │   │   └── Tier: RP/TierBadge (silver)
│   │   └── Quick stats (2 columns, gap 8px)
│   │
│   ├── Subject Cards (Horizontal scroll, gap 12px)
│   │   Each card: Width: 200px, Height: 120px
│   │   (Same content as desktop, compressed)
│   │
│   ├── Upcoming Deadlines (full width, max 3 items)
│   │
│   ├── Recent Badges (full width, 3 columns)
│   │
│   └── Leaderboard (full width, compact)
│
└── RP/MobileNav (role: student, active: home)
    Height: 64px
```

### Dark Mode
- All card BGs: color/surface (#1E293B)
- All borders: color/border (#334155)
- Text follows dark mode tokens
- OPS Ring: Dark zone colors (ring-green #4ADE80, ring-amber #FBBF24, ring-red #F87171, ring-bg #334155)
- Subject card sparklines: Lighter series colors on dark bg

---

## STU-02: OPS BREAKDOWN

### Frame: `RP/Student/STU-02-OPS`

### Desktop Light (1440px)

```
Frame: STU-02-OPS-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: ops)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "OPS Breakdown"
│   │   └── Breadcrumb: "Dashboard > OPS Breakdown"
│   │
│   ├── HERO CARD
│   │   RP/Card (shadow/md, padding/lg)
│   │   Width: 100%
│   │   Layout: Horizontal, gap 32px, alignment: center
│   │   Padding: 32px
│   │
│   │   ├── RP/OPSRing (size: xl, 240px, zone: green, score: 78%)
│   │   │
│   │   ├── "Why is my score 78%?" Section
│   │   │   Layout: Vertical, gap 16px, flex: 1
│   │   │
│   │   │   ├── H3: "Why is my score 78%?"
│   │   │   │   Font: Display/H3 (24px, Semibold)
│   │   │   │
│   │   │   └── Component Breakdown Table
│   │   │       RP/DataTable (state: data)
│   │   │       Width: 100%
│   │   │
│   │   │       Header Row: "Component" | "Weight" | "Score" | "Contribution"
│   │   │       Row Height: 48px
│   │   │
│   │   │       Data:
│   │   │       ├── Exams        | 30% | 82% | 24.6 pts
│   │   │       ├── Assignments  | 20% | 75% | 15.0 pts
│   │   │       ├── Attendance   | 25% | 92% | 23.0 pts
│   │   │       ├── Participation| 15% | 70% | 10.5 pts
│   │   │       ├── Behavior     | 10% | 90% |  9.0 pts
│   │   │       └── TOTAL        |     |     | 82.1/100
│   │   │
│   │   │       Each row has colored weight bar (RP/ProgressBar, sm)
│   │   │       Score cell: colored text (green/amber/red)
│   │   │       TOTAL row: Bold, highlighted
│   │   │
│   │   └── Comparison
│   │       Layout: Horizontal, gap 16px
│   │       ├── "Class avg: 72%" (Body/SM)
│   │       └── "School avg: 68%" (Body/SM)
│
│   ├── TREND CHART
│   │   RP/Card (shadow/sm, padding/md)
│   │   Width: 100%, Height: 320px
│   │
│   │   ├── Header
│   │   │   ├── H5: "OPS Trend"
│   │   │   └── Tabs: [This Term] [This Year] [All Time]
│   │   │
│   │   └── ApexCharts Area Chart (CH-01)
│   │       Width: 100%, Height: 260px
│   │       Data: Multi-term OPS scores
│   │       Series: Student line + Class average dashed
│   │       X-axis: Terms
│   │       Y-axis: 0-100%
│   │       Colors: #1E5FA8 (student), #94A3B8 (class avg)
│   │       Smooth curves, gradient fill
│
│   └── SUBJECT BREAKDOWN
│       Layout: Horizontal, gap 16px
│       Each subject card: RP/Card
│       Width: (100% - gap × n) / n
│
│       ├── Subject name + color accent
│       ├── Score: "85%"
│       ├── RP/ProgressBar (sm, color based on score)
│       └── Trend arrow
│
└── Bottom padding: 48px
```

---

## STU-03: MY TIMETABLE

### Frame: `RP/Student/STU-03-Timetable`

### Desktop Light (1440px)

```
Frame: STU-03-Timetable-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: timetable)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "My Timetable"
│   │   └── Breadcrumb: "Dashboard > Timetable"
│   │
│   ├── WEEK SELECTOR
│   │   RP/Card (padding/sm, shadow/xs)
│   │   Layout: Horizontal, gap 16px, alignment: center
│   │
│   │   ├── RP/Button (ghost, sm): ← Previous Week
│   │   ├── Week label: "June 9 – 13, 2026" (Body/Base, Medium)
│   │   ├── RP/Button (ghost, sm): Next Week →
│   │   └── RP/Button (outline, sm): "Today"
│   │
│   ├── TIMETABLE GRID
│   │   RP/Card (padding/md, shadow/sm)
│   │   Width: 100%
│   │   Overflow: horizontal scroll on mobile
│   │
│   │   Grid: 6 columns (Mon-Fri + Time) × 9 rows (8AM-4PM)
│   │   Column width: (100% - 80px) / 5 = auto
│   │   Time column: 80px fixed
│   │   Row height: 60px
│   │   Gap: 2px
│   │
│   │   Header row:
│   │   ├── Time column: empty
│   │   ├── "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday"
│   │   │   Font: Label/Base (14px, Medium)
│   │   │   Text-align: center
│   │   │   Today: BG color/secondary, color/inverse-text
│   │   │
│   │   Data rows:
│   │   ├── Time labels: "8:00" through "4:00" (Body/XS, muted)
│   │   └── Session blocks (absolute positioned within cells):
│   │       Each block:
│   │       ├── Padding: 4px 8px
│   │       ├── Border-radius: 6px
│   │       ├── BG: Subject color at 10% opacity
│   │       ├── Border-left: 3px subject color
│   │       ├── Subject name (Body/XS, Medium)
│   │       ├── Teacher name (Body/XS, muted)
│   │       └── Room/Online badge (Body/XS)
│   │
│   │       Online badge: 🟢 + "Online"
│   │       Physical badge: 🏫 + "Room 12"
│   │
│   └── LEGEND
│       Layout: Horizontal, gap 16px
│       Each: Colored dot + subject name
│       Font: Body/XS
│
└── Bottom padding: 48px
```

### Mobile (375px)

```
├── Content: Padding 16px
├── Week selector: Full width, stacked
├── Timetable: Horizontal scroll container
│   ├── Min-width: 600px (forces scroll)
│   ├── Each column: 120px min
│   └── Touch: Swipe left/right to scroll
└── Legend: Horizontal scroll
```

---

## STU-04: SESSION DETAIL

### Frame: `RP/Student/STU-04-Session`

### Desktop Light

```
Frame: STU-04-Session-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: sessions)
├── RP/Topbar (student)
│
├── Content Area
│   Max-width: 800px (centered)
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Breadcrumb: "Dashboard > Sessions > Mathematics - JSS 2"
│   │
│   ├── SESSION CARD
│   │   RP/Card (shadow/md, padding/lg)
│   │   Layout: Vertical, gap 20px
│   │
│   │   ├── Header Row (Horizontal, justify: space-between)
│   │   │   ├── H2: "Mathematics - JSS 2"
│   │   │   │   Font: Display/H2 (30px, Bold)
│   │   │   └── RP/Badge (type: info): "Online"
│   │   │
│   │   ├── Info Grid (2 columns, gap 16px)
│   │   │   ├── Date: "📅 June 12, 2026"
│   │   │   ├── Time: "⏰ 10:00 AM - 11:00 AM"
│   │   │   ├── Teacher: "👨‍🏫 Dr. Mensah"
│   │   │   ├── Duration: "⏱ 60 minutes"
│   │   │   ├── Room: "💻 Zoom Meeting"
│   │   │   └── Status: RP/Badge (success): "In Progress"
│   │   │
│   │   ├── Divider
│   │   │
│   │   ├── Session Description
│   │   │   "Topic: Algebraic Expressions. Please ensure you have your calculator ready."
│   │   │   Font: Body/Base, color/body-text
│   │   │
│   │   ├── Divider
│   │   │
│   │   ├── ACTION BUTTONS
│   │   │   Layout: Horizontal, gap 12px
│   │   │
│   │   │   ├── RP/Button (primary, lg)
│   │   │   │   Icon: video (16px, left)
│   │   │   │   Text: "Join Session"
│   │   │   │   → POST /classroom/{session}/join
│   │   │   │   → Navigate to STU-05
│   │   │   │
│   │   │   └── RP/Button (outline, lg)
│   │   │       Icon: download (16px, left)
│   │   │       Text: "Download Materials"
│   │   │
│   │   └── Status indicator
│   │       "🟢 Session is live — 12 students connected"
│   │       Font: Body/SM, color/success
│   │
│   ├── ATTENDANCE HISTORY
│   │   RP/Card (padding/md)
│   │   Layout: Vertical, gap 12px
│   │
│   │   ├── H5: "Your Attendance"
│   │   ├── Stats row:
│   │   │   ├── "Present: 8" (green badge)
│   │   │   ├── "Late: 1" (amber badge)
│   │   │   └── "Absent: 1" (red badge)
│   │   └── Rate: "90% attendance" (Body/Base, Medium)
│   │
│   └── PAST SESSIONS
│       List of previous sessions (max 5)
│       Each: Date + Topic + Status badge
│
└── Bottom padding: 48px
```

---

## STU-05: LIVE CLASSROOM (Student View)

### Frame: `RP/Student/STU-05-Classroom`

### Desktop (1440px) — Full viewport

```
Frame: STU-05-Classroom-Desktop-Light
Width: 1440px, Height: 100vh (fullscreen)
BG: #000 (video bg)

├── TOP BAR (overlay, 48px height)
│   BG: rgba(0,0,0,0.7)
│   Layout: Horizontal, justify: space-between, alignment: center
│   Padding: 0 16px
│
│   ├── LEFT: Session info
│   │   "Mathematics - JSS 2" (Body/SM, White)
│   │   Separator: "•"
│   │   "Dr. Mensah" (Body/SM, rgba(255,255,255,0.7))
│   │
│   ├── CENTER: Timer
│   │   "00:45:12" (Mono/Base, White)
│   │
│   └── RIGHT: Students connected
│       "12 students" (Body/SM, White)
│       Online dot indicator
│
├── VIDEO AREA (fill)
│   Width: 100%, Height: calc(100vh - 48px - 72px)
│   BG: #000
│   Layout: Zoom Video SDK grid
│
│   ├── Speaker view (dominant speaker large)
│   └── Gallery view (small thumbnails, horizontal scroll)
│
│   Note: Actual video content rendered by Zoom Video SDK
│   This frame shows the container + overlay elements only
│
├── CONTROLS BAR (bottom, 72px height)
│   BG: rgba(0,0,0,0.8)
│   Layout: Horizontal, gap 16px, alignment: center, justify: center
│   Padding: 0 24px
│
│   ├── RP/Button (circle, 48px)
│   │   Icon: mic / mic-off (20px, White)
│   │   BG: rgba(255,255,255,0.1)
│   │   Hover: rgba(255,255,255,0.2)
│   │   Active: rgba(255,255,255,0.3)
│   │   Tooltip: "Toggle Microphone"
│   │
│   ├── RP/Button (circle, 48px)
│   │   Icon: video / video-off (20px, White)
│   │   Same styling as mic
│   │   Tooltip: "Toggle Camera"
│   │
│   ├── RP/Button (circle, 48px)
│   │   Icon: message-square (20px, White)
│   │   Badge: unread count (optional)
│   │   Tooltip: "Chat"
│   │   → Opens chat panel (slide-in from right, 320px)
│   │
│   ├── RP/Button (circle, 48px)
│   │   Icon: users (20px, White)
│   │   Tooltip: "Participants"
│   │   → Opens participants panel
│   │
│   └── RP/Button (danger, md)
│       Icon: phone-off (16px, left)
│       Text: "Leave"
│       BG: color/danger
│       → POST /classroom/{session}/leave
│       → Confirm modal: "Leave Session?"
│       → Navigate to STU-04
│
│   NOTE: No recording controls (teacher only)
│   NOTE: No screen share (student can't share)
```

### Mobile (375px)
- Same structure, controls bar: 64px
- Video area: Full width
- Controls: Icons only (no text labels)
- Participant grid: 2 columns

---

## STU-06: ASSIGNMENTS LIST

### Frame: `RP/Student/STU-06-Assignments`

### Desktop Light

```
Frame: STU-06-Assignments-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: assignments)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "Assignments"
│   │   └── Breadcrumb: "Dashboard > Assignments"
│   │
│   ├── FILTER BAR (RP/FilterBar)
│   │   Search + Subject filter + Status filter
│   │
│   ├── TABS (RP/Tabs, variant: underline)
│   │   [All (12)] [Pending (3)] [Submitted (5)] [Graded (4)]
│   │
│   ├── ASSIGNMENTS TABLE
│   │   RP/DataTable (state: data)
│   │   Width: 100%
│   │
│   │   Columns:
│   │   ├── Title (text, flex: 2)
│   │   │   Display: Title + Subject tag (colored pill)
│   │   │
│   │   ├── Subject (text, flex: 1)
│   │   │   Display: Subject name
│   │   │
│   │   ├── Due Date (text, flex: 1)
│   │   │   Display: "Jun 15, 2026"
│   │   │   Overdue: Red text + "Overdue" badge
│   │   │
│   │   ├── Status (badge, flex: 1)
│   │   │   "Pending" → RP/Badge (warning)
│   │   │   "Submitted" → RP/Badge (info)
│   │   │   "Graded" → RP/Badge (success) + score
│   │   │
│   │   └── Action (button, flex: 0)
│   │       "Start" / "Continue" / "View" → STU-07
│   │
│   │   Rows: Max 10 per page
│   │   Pagination: RP/Pagination (numbers)
│   │
│   ├── Empty states per tab:
│   │   "No pending assignments" / "No submitted" / "No graded"
│   │
│   └── Summary cards (above table)
│       Layout: Horizontal, gap 16px
│       ├── "Total: 12" (KPI card)
│       ├── "Pending: 3" (KPI card, warning)
│       ├── "Graded: 4" (KPI card, success)
│       └── "Avg Score: 78%" (KPI card)
│
└── Bottom padding: 48px
```

---

## STU-07: ASSIGNMENT DETAIL

### Frame: `RP/Student/STU-07-Assignment`

### Desktop Light

```
Frame: STU-07-Assignment-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student)
├── RP/Topbar (student)
│
├── Content Area
│   Max-width: 800px (centered)
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Breadcrumb: "Dashboard > Assignments > Math Quiz Ch.5"
│   │
│   ├── ASSIGNMENT HEADER
│   │   RP/Card (shadow/sm, padding/lg)
│   │   Layout: Vertical, gap 16px
│   │
│   │   ├── Title Row (Horizontal, justify: space-between)
│   │   │   ├── H2: "Math Quiz Chapter 5"
│   │   │   └── RP/Badge (success): "Graded" / RP/Badge (warning): "Pending"
│   │   │
│   │   ├── Meta Row (Horizontal, gap 16px)
│   │   │   ├── Subject: "Mathematics" (colored pill)
│   │   │   ├── Due: "📅 Jun 15, 2026 11:59 PM"
│   │   │   ├── Max Score: "100 points"
│   │   │   └── Duration: "60 minutes"
│   │   │
│   │   ├── Description
│   │   │   "Complete all 15 questions on algebraic expressions. Show your working for partial credit."
│   │   │
│   │   └── Grading info (if graded)
│   │       "Your Score: 78/100 (78%)"
│   │       RP/ProgressBar (lg, primary, 78%)
│   │       Grade: "B+" (RP/Badge, success)
│   │
│   ├── QUESTIONS LIST (if question-based)
│   │   RP/Card (padding/md)
│   │   Vertical list of question cards
│   │
│   │   Each question:
│   │   ├── Number: "Q1" (Label/SM)
│   │   ├── Question text (Body/Base)
│   │   ├── Your answer (Body/SM, indented)
│   │   ├── Correct answer (if show_correct_answers): Body/SM, color/success
│   │   └── Feedback (if available): Body/SM, color/info
│   │
│   ├── SUBMISSION SECTION
│   │   If not yet submitted:
│   │   ├── File upload area (RP/FileUpload)
│   │   ├── RP/Button (primary, lg): "Submit Assignment"
│   │   └── Warning: "You can only submit once"
│   │
│   │   If submitted:
│   │   ├── "Submitted on: Jun 14, 2026 at 3:45 PM"
│   │   ├── Submitted file: download link
│   │   └── RP/Badge (info): "Awaiting grading" or score
│   │
│   │   If graded:
│   │   ├── Score display
│   │   ├── Feedback section
│   │   └── Correct answers (if allowed)
│   │
│   └── ACTIONS
│       RP/Button (ghost): "Back to Assignments"
│
└── Bottom padding: 48px
```

---

## STU-08: EXAM LIST

### Frame: `RP/Student/STU-08-Exams`

### Desktop Light

```
Frame: STU-08-Exams-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: exams)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "Exams"
│   │   └── Breadcrumb: "Dashboard > Exams"
│   │
│   ├── TABS (RP/Tabs, variant: underline)
│   │   [Upcoming (2)] [In Progress (0)] [Completed (5)]
│   │
│   ├── EXAM CARDS
│   │   Layout: Vertical, gap 16px
│   │
│   │   Each exam card:
│   │   RP/Card (shadow/sm, padding/md, hover)
│   │   Width: 100%
│   │   Layout: Horizontal, gap 16px, alignment: center
│   │   Padding: 16px
│   │
│   │   ├── LEFT: Exam info (flex: 1)
│   │   │   ├── Title: "Mid-Term Mathematics Exam" (Display/H6, Medium)
│   │   │   ├── Meta: "Mathematics • JSS 2 • 30 questions" (Body/SM, muted)
│   │   │   └── Meta: "📅 June 20, 2026 • ⏱ 90 min" (Body/SM, muted)
│   │   │
│   │   ├── CENTER: Attempt info
│   │   │   "Attempt 1 of 3" (Body/SM)
│   │   │   OR "Unlimited attempts"
│   │   │   OR "1 attempt remaining" (warning color)
│   │   │
│   │   └── RIGHT: Action
│   │       ├── "Start Exam" → RP/Button (primary, md) → STU-09
│   │       ├── "Continue" → RP/Button (accent, md) → STU-09
│   │       ├── "View Result" → RP/Button (outline, md) → STU-10
│   │       └── "Retry" → RP/Button (accent, md) → STU-09
│   │
│   │   Locked state: Opacity 0.5, "🔒 Available June 20"
│   │
│   └── Empty state per tab
│
└── Bottom padding: 48px
```

---

## STU-09: EXAM INTERFACE

### Frame: `RP/Student/STU-09-Exam`

### Desktop (1440px) — Full viewport exam mode

```
Frame: STU-09-Exam-Desktop-Light
Width: 1440px, Height: 100vh
BG: color/background

├── TOP BAR (fixed, 56px)
│   BG: color/surface
│   Border-bottom: 1px color/border
│   Layout: Horizontal, justify: space-between, alignment: center
│   Padding: 0 24px
│
│   ├── LEFT: Exam info
│   │   "Mid-Term Mathematics Exam" (Body/Base, Medium)
│   │   Separator: "•"
│   │   "Attempt 1 of 3" (Body/SM, muted)
│   │
│   ├── CENTER: Timer
│   │   ⏱ "01:23:45" (Mono/LG, Bold)
│   │   Warning: < 10 min → color/danger, pulsing
│   │
│   └── RIGHT: Progress
│       "Question 5 of 30" (Body/SM)
│       Progress: ████████░░░░ 5/30 (RP/ProgressBar, sm, 16.7%)
│
├── MAIN CONTENT
│   Layout: Horizontal
│   Height: calc(100vh - 56px - 72px)
│
│   ├── QUESTION AREA (flex: 1)
│   │   Padding: 32px 48px
│   │   Layout: Vertical, gap 24px
│   │   Max-width: 800px (centered)
│   │
│   │   ├── Question header
│   │   │   "Question 5 of 30" (Label/Base, muted)
│   │   │   Points: "10 points" (RP/Badge, info, sm)
│   │   │
│   │   ├── Question text
│   │   │   "Solve for x: 3x + 7 = 22"
│   │   │   Font: Body/LG (18px, Regular)
│   │   │
│   │   ├── ANSWER INPUT (varies by question type):
│   │   │
│   │   │   MC: Radio buttons (vertical, gap 12px)
│   │   │   ├── ○ x = 3
│   │   │   ├── ○ x = 5
│   │   │   ├── ○ x = 7
│   │   │   └── ○ x = 15
│   │   │
│   │   │   Multi Select: Checkboxes (vertical, gap 12px)
│   │   │   ├── ☐ Option A
│   │   │   └── ☐ Option B (can select multiple)
│   │   │
│   │   │   T/F: Radio buttons (horizontal, gap 24px)
│   │   │   ├── ○ True  ○ False
│   │   │
│   │   │   Short Answer: Text input (full width)
│   │   │   └── RP/Input (text, lg)
│   │   │
│   │   │   Essay: Rich textarea
│   │   │   └── RP/Input (textarea, lg, rows: 8)
│   │   │       Word count: "0 / 500"
│   │   │
│   │   │   Numeric: Number input
│   │   │   └── RP/Input (number, lg)
│   │   │
│   │   │   Fill Blank: Inline text inputs
│   │   │   "The capital of Ghana is [_____]" (inline input)
│   │   │
│   │   │   Matching: Drag-and-drop pairs
│   │   │   Left items → Right items (dropdown or drag)
│   │   │
│   │   │   File Upload: Dropzone
│   │   │   └── RP/FileUpload (state: empty)
│   │   │
│   │   └── Navigation buttons
│   │       Layout: Horizontal, justify: space-between
│   │       ├── RP/Button (ghost): "← Previous"
│   │       └── RP/Button (primary): "Next →"
│   │           Last question: "Next →" changes to "Review & Submit"
│   │
│   └── QUESTION NAVIGATOR (sidebar, 240px, desktop only)
│       BG: color/surface
│       Border-left: 1px color/border
│       Padding: 16px
│       Layout: Vertical, gap 8px
│
│       ├── H5: "Questions"
│       ├── Grid: 6 columns of numbered circles
│       │   Each circle: 36×36px, centered number
│       │
│       │   States:
│       │   ├── Answered: BG color/secondary, text white
│       │   ├── Current: BG color/accent, text white, ring
│       │   ├── Unanswered: BG color/background, text body
│       │   └── Flagged: BG color/warning, flag icon
│       │
│       ├── Divider
│       ├── "Answered: 5" (Body/XS)
│       ├── "Unanswered: 25" (Body/XS)
│       └── "Flagged: 2" (Body/XS)
│
├── BOTTOM BAR (fixed, 72px)
│   BG: color/surface
│   Border-top: 1px color/border
│   Layout: Horizontal, justify: space-between, alignment: center
│   Padding: 0 24px
│
│   ├── LEFT: Flag button
│   │   RP/Button (ghost, sm): "🚩 Flag for Review"
│   │   Toggles flagged state for current question
│   │
│   ├── CENTER: Question nav (prev/next)
│   │   Same as in-question navigation
│   │
│   └── RIGHT: Submit
│       RP/Button (accent, lg): "Review & Submit"
│       → Opens confirmation modal:
│         "Submit Exam?"
│         "Answered: 25/30"
│         "Unanswered: 5"
│         [Continue Exam] [Submit]
│
│       On submit:
│       → POST /exams/{exam}/submit
│       → exam_attempts record created
│       → Navigate to STU-10
│
├── CONFIRMATION MODAL (RP/Modal, md)
│   ├── Header: "Submit Exam?"
│   ├── Content:
│   │   "You have answered 25 out of 30 questions."
│   │   "5 questions are unanswered."
│   │   RP/Banner (warning): "You cannot change answers after submission."
│   └── Footer:
│       [Continue Exam] (ghost)  [Submit] (accent)
```

---

## STU-10: EXAM RESULT

### Frame: `RP/Student/STU-10-Result`

### Desktop Light

```
Frame: STU-10-Result-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student)
├── RP/Topbar (student)
│
├── Content Area
│   Max-width: 800px (centered)
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Breadcrumb: "Dashboard > Exams > Mid-Term Math"
│   │
│   ├── RESULT HEADER
│   │   RP/Card (shadow/md, padding/lg)
│   │   Layout: Vertical, gap 16px, alignment: center
│   │   Padding: 32px
│   │
│   │   ├── Score Display (based on grading_type):
│   │   │   Percentage: "78%" (Display/H1, 36px, Bold, color/secondary)
│   │   │   Letter: "B+" (Display/H1, color/success)
│   │   │   Numeric: "78 / 100" (Display/H1)
│   │   │   Custom: "Good (70-89%)" with color band
│   │   │
│   │   ├── Status
│   │   │   "Passed" → RP/Badge (success, md): "✓ Passed"
│   │   │   "Failed" → RP/Badge (danger, md): "✗ Failed"
│   │   │   Passing score: 50%
│   │   │
│   │   ├── Score breakdown
│   │   │   "Correct: 22/30 • Partial: 3/30 • Wrong: 5/30"
│   │   │   Font: Body/SM, color/muted-text
│   │   │
│   │   └── Attempt info
│   │       "Attempt 1 of 3" (Body/SM)
│   │       "Remaining: 2 attempts" (Body/XS, muted)
│   │
│   ├── FEEDBACK SECTION (if show_feedback_after condition met)
│   │   RP/Card (padding/md)
│   │   Layout: Vertical, gap 12px
│   │
│   │   ├── H5: "Teacher Feedback"
│   │   └── Feedback text (Body/Base)
│   │
│   │   If show_correct_answers:
│   │   ├── Each question reviewed
│   │   │   ├── Question text
│   │   │   ├── Your answer (color/success if correct, color/danger if wrong)
│   │   │   ├── Correct answer (if different)
│   │   │   └── Explanation (if provided)
│   │
│   ├── RETAKE
│   │   If attempts remaining:
│   │   RP/Button (accent, lg): "Retry Exam" → STU-09
│   │   "You have 2 attempts remaining"
│   │
│   └── ACTIONS
│       RP/Button (ghost): "Back to Exams"
│
└── Bottom padding: 48px
```

---

## STU-11: RESOURCE LIBRARY

### Frame: `RP/Student/STU-11-Resources`

### Desktop Light

```
Frame: STU-11-Resources-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: resources)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "Resource Library"
│   │   └── Breadcrumb: "Dashboard > Resources"
│   │
│   ├── FILTER BAR
│   │   Search + Subject filter + Type filter (PDF/Video/Link)
│   │
│   ├── RESOURCE GRID
│   │   Layout: 3 columns (desktop), gap 16px
│   │
│   │   Each resource card:
│   │   RP/Card (shadow/sm, hover)
│   │   Width: (100% - 32px) / 3
│   │   Layout: Vertical, gap 0
│   │
│   │   ├── File preview/icon (120px height)
│   │   │   PDF: Red icon on grey bg
│   │   │   Video: Play button on thumbnail
│   │   │   Link: Globe icon
│   │   │
│   │   ├── Content (padding: 16px)
│   │   │   ├── Title (Body/SM, Medium)
│   │   │   ├── Subject tag (colored pill)
│   │   │   ├── Size/date (Body/XS, muted)
│   │   │   └── RP/Button (ghost, sm): "Download" / "View"
│   │
│   │   Empty state: RP/EmptyState
│   │   "No resources available"
│
└── Bottom padding: 48px
```

---

## STU-12: MY ATTENDANCE

### Frame: `RP/Student/STU-12-Attendance`

### Desktop Light

```
Frame: STU-12-Attendance-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: attendance)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "My Attendance"
│   │   └── Breadcrumb: "Dashboard > Attendance"
│   │
│   ├── KPI ROW
│   │   Layout: Horizontal, gap 16px
│   │   ├── KPI Card: "Overall Rate: 92%" (success)
│   │   ├── KPI Card: "Present: 46" (info)
│   │   ├── KPI Card: "Late: 3" (warning)
│   │   └── KPI Card: "Absent: 2" (danger)
│   │
│   ├── CALENDAR HEATMAP
│   │   RP/Card (shadow/sm, padding/md)
│   │   Width: 100%
│   │
│   │   ├── Month Header
│   │   │   Layout: Horizontal, justify: space-between
│   │   │   ├── RP/Button (ghost, sm): ← Previous
│   │   │   ├── "June 2026" (Display/H5, Medium)
│   │   │   └── RP/Button (ghost, sm): Next →
│   │   │
│   │   ├── Day Labels
│   │   │   "Mon Tue Wed Thu Fri" (Label/SM, muted)
│   │   │   5 columns, centered
│   │   │
│   │   ├── Month Grid
│   │   │   5 rows × 5 columns (weekdays only)
│   │   │   Cell: 48×48px, gap 4px
│   │   │
│   │   │   Cell colors:
│   │   │   ├── Present: gamification/heatmap-present (#22C55E)
│   │   │   ├── Late: gamification/heatmap-late (#F59E0B)
│   │   │   ├── Absent: gamification/heatmap-absent (#DC2626)
│   │   │   ├── No class: gamification/heatmap-noclass (#E2E8F0)
│   │   │   └── Today: Ring 2px color/secondary
│   │   │
│   │   │   Hover tooltip:
│   │   │   ├── Date: "June 12, 2026"
│   │   │   ├── Status: "Present" (green dot)
│   │   │   └── Subject: "Mathematics"
│   │   │
│   │   └── Legend
│   │       Layout: Horizontal, gap 16px
│   │       ├── ● Present (green dot + text)
│   │       ├── ● Late (amber dot)
│   │       ├── ● Absent (red dot)
│   │       └── ● No Class (grey dot)
│   │
│   ├── BY-SUBJECT BREAKDOWN
│   │   RP/Card (padding/md)
│   │   Layout: Vertical, gap 12px
│   │
│   │   ├── H5: "Attendance by Subject"
│   │   │
│   │   └── Table
│   │       Each row:
│   │       ├── Subject name (with color accent)
│   │       ├── Attendance rate: "95%"
│   │       ├── RP/ProgressBar (sm, color based on rate)
│   │       └── Detail: "19/20 sessions"
│   │
│   └── TREND CHART
│       RP/Card (padding/md)
│       H5: "Attendance Trend"
│       ApexCharts Area chart (CH-11)
│       X-axis: Months, Y-axis: 0-100%
│       Series: Attendance rate over time
│
└── Bottom padding: 48px
```

---

## STU-13: MY GOALS

### Frame: `RP/Student/STU-13-Goals`

### Desktop Light

```
Frame: STU-13-Goals-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: goals)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "My Goals"
│   │   └── Breadcrumb: "Dashboard > Goals"
│   │
│   ├── TABS
│   │   [Active (3)] [Completed (5)] [All]
│   │
│   ├── GOAL CARDS
│   │   Layout: Vertical, gap 16px
│   │
│   │   Each goal:
│   │   RP/Card (shadow/sm, padding/md)
│   │   Width: 100%
│   │   Layout: Vertical, gap 12px
│   │
│   │   ├── Header (Horizontal, justify: space-between)
│   │   │   ├── Goal title: "Improve Math score to 85%" (Display/H6)
│   │   │   └── RP/Badge (info): "Active"
│   │   │
│   │   ├── Subject: "Mathematics" (colored pill)
│   │   │
│   │   ├── Progress
│   │   │   Layout: Horizontal, gap 8px, alignment: center
│   │   │   ├── RP/ProgressBar (md, primary, 65%)
│   │   │   │   Width: flex: 1
│   │   │   └── "65%" (Body/SM, Bold)
│   │   │
│   │   ├── Goal Details (Horizontal, gap 16px)
│   │   │   ├── "Target: 85%" (Body/SM, muted)
│   │   │   ├── "Current: 78%" (Body/SM, muted)
│   │   │   └── "Due: Dec 31, 2026" (Body/SM, muted)
│   │   │
│   │   └── Teacher note (if any)
│   │       "Keep practicing algebra exercises daily." (Body/SM, italic)
│   │       Teacher: Dr. Mensah
│   │
│   │   Empty state: RP/EmptyState
│   │   "No active goals set"
│   │   Icon: target
│
└── Bottom padding: 48px
```

---

## STU-14: ACHIEVEMENTS

### Frame: `RP/Student/STU-14-Achievements`

### Desktop Light

```
Frame: STU-14-Achievements-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: achievements)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "Achievements"
│   │   └── Breadcrumb: "Dashboard > Achievements"
│   │
│   ├── TIER PROGRESS
│   │   RP/Card (shadow/md, padding/lg)
│   │   Width: 100%
│   │   Layout: Horizontal, gap 24px, alignment: center
│   │   Padding: 32px
│   │
│   │   ├── Current Tier Badge (large)
│   │   │   RP/TierBadge (silver, highlighted)
│   │   │   Scale: 1.5x → 48px height
│   │   │
│   │   ├── Tier Progress
│   │   │   Layout: Vertical, gap 8px, flex: 1
│   │   │
│   │   │   ├── "Silver → Gold" (Body/Base, Medium)
│   │   │   ├── Points: "1,250 / 1,500 pts" (Body/SM, muted)
│   │   │   └── RP/ProgressBar (lg, accent, 83%)
│   │   │       "250 points to Gold"
│   │   │
│   │   └── Tier ladder (horizontal, all 5 tiers)
│   │       🥉 Bronze (0) → 🥈 Silver (500) → 🥇 Gold (1,500) → 💎 Platinum (3,000) → 👑 Diamond (6,000)
│   │       Current tier highlighted
│   │       Future tiers: greyed
│   │
│   ├── STREAK TRACKER
│   │   RP/Card (shadow/sm, padding/md)
│   │   Layout: Horizontal, gap 24px, alignment: center
│   │
│   │   ├── RP/StreakBadge (lg): 🔥 12 days
│   │   │
│   │   ├── Streak stats
│   │   │   ├── "Current: 12 days" (Body/Base, Bold)
│   │   │   ├── "Longest: 18 days" (Body/SM, muted)
│   │   │   └── "Total points from streaks: 210" (Body/XS, muted)
│   │   │
│   │   └── Milestone badges (horizontal row)
│   │       Each milestone:
│   │       ├── 7 days: ✓ (green, earned)
│   │       ├── 14 days: ○ (locked, next milestone)
│   │       ├── 30 days: 🔒 (locked)
│   │       ├── 60 days: 🔒 (locked)
│   │       └── 100 days: 🔒 (locked)
│   │
│   │       Earned: Full color, green border
│   │       Next: Outline, amber border, "2 days to go"
│   │       Locked: Greyscale, lock icon
│   │
│   ├── BADGE COLLECTION
│   │   Layout: Vertical, gap 16px
│   │
│   │   ├── H5: "Badge Collection"
│   │   │
│   │   └── Badge Grid (4 columns, gap 16px)
│   │       Each badge:
│   │       ├── Badge icon (64px, circular)
│   │       │   Earned: Full color, subtle glow animation
│   │       │   Locked: Greyscale + lock overlay (40% opacity)
│   │       ├── Name (Body/SM, Medium, centered)
│   │       └── Date (Body/XS, muted, centered): "Earned Jun 10"
│   │
│   │       Badge types:
│   │       ├── first_submission 📝
│   │       ├── first_exam_pass 🎉
│   │       ├── streak_7 🔥
│   │       ├── streak_14 🔥
│   │       ├── streak_30 🔥
│   │       ├── perfect_attendance ✅
│   │       ├── gold_tier 🥇
│   │       ├── diamond_tier 👑
│   │       └── (more as earned)
│   │
│   └── POINTS HISTORY
│       RP/Card (padding/md)
│       H5: "Recent Points"
│       RP/Timeline (variant: vertical)
│       Each entry:
│       ├── "+10 pts" (color/success) "Assignment completed"
│       ├── "+5 pts" (color/success) "Streak milestone (7 days)"
│       └── "+15 pts" (color/success) "Exam passed"
│       Date (Body/XS, muted)
│
└── Bottom padding: 48px
```

---

## STU-15: LEADERBOARD

### Frame: `RP/Student/STU-15-Leaderboard`

### Desktop Light

```
Frame: STU-15-Leaderboard-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: leaderboard)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "Leaderboard"
│   │   └── Breadcrumb: "Dashboard > Leaderboard"
│   │
│   ├── YOUR POSITION CARD
│   │   RP/Card (shadow/sm, padding/md)
│   │   BG: color/secondary at 5% opacity
│   │   Border: 1px color/secondary
│   │   Layout: Horizontal, gap 16px, alignment: center
│   │
│   │   ├── RP/Avatar (lg, has-image)
│   │   ├── Rank: "#5" (Display/H3, 24px, Bold)
│   │   ├── Name: "Amara Asante" (Body/Base, Medium)
│   │   ├── Score: "78%" (KPI/Value)
│   │   └── Tier: RP/TierBadge (silver)
│   │
│   ├── TABS + FILTERS
│   │   Layout: Horizontal, justify: space-between
│   │   ├── Tabs: [Class] [School] (RP/Tabs, pill)
│   │   └── Filter: [This Term ▾] (RP/Select, sm)
│   │
│   ├── LEADERBOARD TABLE
│   │   RP/Card (padding/none)
│   │   Width: 100%
│   │
│   │   Rows: (min 10, max 50)
│   │   Each row:
│   │   ├── Height: 56px
│   │   ├── Padding: 0 16px
│   │   ├── Layout: Horizontal, gap 12px, alignment: center
│   │   ├── Border-bottom: 1px color/divider
│   │   │
│   │   ├── Rank: "1" / "🥇" / "🥈" / "🥉" (16px, Bold for top 3)
│   │   ├── RP/Avatar (sm, has-image)
│   │   ├── Name (Body/Base, flex: 1)
│   │   ├── Score: "78%" (Body/Base, Bold)
│   │   └── Tier badge: 🥈 (14px)
│   │
│   │   Current student row: BG rgba(30,95,168,0.08), border-left 3px color/secondary
│   │   Top 3 rows: Medal icons + highlighted bg
│   │
│   └── Pagination: RP/Pagination
│
└── Bottom padding: 48px
```

---

## STU-16: MESSAGES

### Frame: `RP/Student/STU-16-Messages`

### Desktop Light

```
Frame: STU-16-Messages-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: messages)
├── RP/Topbar (student)
│
├── Content Area
│   Padding: 0
│   Layout: Horizontal
│   Height: calc(100vh - 64px)
│
│   ├── CONVERSATION LIST (320px width)
│   │   BG: color/surface
│   │   Border-right: 1px color/border
│   │   Layout: Vertical
│   │
│   │   ├── Header (56px)
│   │   │   "Messages" (H5) + Compose button (RP/Button, ghost, icon: plus)
│   │   │
│   │   ├── Search
│   │   │   RP/SearchInput (sm)
│   │   │   Padding: 0 12px 12px
│   │   │
│   │   └── Conversation List (scrollable)
│   │       Each conversation:
│   │       ├── Height: 72px
│   │       ├── Padding: 12px
│   │       ├── Layout: Horizontal, gap 12px
│   │       ├── Border-bottom: 1px color/divider
│   │       │
│   │       ├── RP/Avatar (sm, has-image)
│   │       ├── Info (flex: 1)
│   │       │   ├── Name (Body/SM, Medium) + time (Body/XS, muted)
│   │       │   └── Preview: "Thanks for the update!" (Body/XS, muted, truncated)
│   │       └── Unread indicator (8px dot, color/secondary)
│   │
│   │       Active conversation: BG rgba(30,95,168,0.08)
│   │
│   ├── MESSAGE AREA (fill)
│   │   Layout: Vertical
│   │
│   │   ├── Chat Header (56px)
│   │   │   BG: color/surface
│   │   │   Border-bottom: 1px color/border
│   │   │   Layout: Horizontal, gap 12px, alignment: center
│   │   │   ├── RP/Avatar (sm)
│   │   │   ├── "Dr. Mensah" (Body/Base, Medium)
│   │   │   └── "Online" / "Last seen 2h ago" (Body/XS, muted)
│   │   │
│   │   ├── Messages (scrollable, fill)
│   │   │   Padding: 16px
│   │   │   Layout: Vertical, gap 8px
│   │   │
│   │   │   Each message:
│   │   │   ├── Max-width: 70%
│   │   │   ├── Padding: 10px 14px
│   │   │   ├── Border-radius: 12px
│   │   │   ├── Body/SM (14px)
│   │   │   └── Time (Body/XS, muted)
│   │   │
│   │   │   Sent (right-aligned):
│   │   │   BG: color/secondary, color/inverse-text
│   │   │   Border-radius: 12px 12px 4px 12px
│   │   │
│   │   │   Received (left-aligned):
│   │   │   BG: color/background, color/body-text
│   │   │   Border-radius: 12px 12px 12px 4px
│   │   │
│   │   └── Message Input (80px)
│   │       BG: color/surface
│   │       Border-top: 1px color/border
│   │       Layout: Horizontal, gap 8px, padding: 12px
│   │       ├── RP/Button (ghost, icon: paperclip)
│   │       ├── RP/Input (text): "Type a message..."
│   │       └── RP/Button (primary, icon: send)
│   │
│   └── Empty state (when no conversation selected)
│       RP/EmptyState
│       "Select a conversation to start messaging"
│
└── Mobile: Full screen conversation list → tap to open chat
```

---

## STU-17: NOTIFICATION CENTER

### Frame: `RP/Student/STU-17-Notifications`

### Desktop Light

```
Frame: STU-17-Notifications-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: notifications)
├── RP/Topbar (student)
│
├── Content Area
│   Max-width: 720px (centered)
│   Padding: 24px
│   Layout: Vertical, gap 16px
│
│   ├── Page Header
│   │   ├── H1: "Notifications"
│   │   └── RP/Button (ghost, sm): "Mark All as Read"
│   │
│   ├── TABS
│   │   [All] [Unread] [Academic] [Financial] [System]
│   │
│   ├── NOTIFICATION LIST
│   │   Layout: Vertical, gap 0
│   │
│   │   Each notification:
│   │   RP/Card (padding/md, border, no shadow)
│   │   Width: 100%
│   │   Layout: Horizontal, gap 12px, alignment: start
│   │   Padding: 16px
│   │
│   │   ├── Unread indicator: 8px dot (color/secondary)
│   │   │   Read: hidden
│   │   │
│   │   ├── Icon (40px, circular)
│   │   │   Academic: 📚 (info bg)
│   │   │   Financial: 💰 (warning bg)
│   │   │   Attendance: 📅 (danger bg)
│   │   │   Achievement: 🏆 (accent bg)
│   │   │   System: ⚙ (neutral bg)
│   │   │
│   │   ├── Content (flex: 1)
│   │   │   ├── Title (Body/SM, Medium)
│   │   │   │   "Assignment graded: Math Quiz Ch.5"
│   │   │   │   Unread: Bold
│   │   │   │
│   │   │   ├── Preview (Body/XS, muted)
│   │   │   │   "You scored 78/100. View your results for detailed feedback."
│   │   │   │
│   │   │   └── Time (Body/XS, muted)
│   │   │       "2 hours ago"
│   │   │
│   │   └── Actions
│   │       "View" button or navigation link
│   │
│   │   Unread: BG rgba(30,95,168,0.04)
│   │   Read: BG transparent
│   │
│   ├── Pagination or infinite scroll
│   │
│   └── Empty state
│       "You're all caught up! 🎉"
│
└── Bottom padding: 48px
```

---

## STU-18: NOTIFICATION PREFERENCES

### Frame: `RP/Student/STU-18-NotificationPrefs`

### Desktop Light

```
Frame: STU-18-NotificationPrefs-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: notifications)
├── RP/Topbar (student)
│
├── Content Area
│   Max-width: 720px (centered)
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "Notification Preferences"
│   │   └── Breadcrumb: "Dashboard > Notification Preferences"
│   │
│   ├── PREFERENCES TABLE
│   │   RP/Card (padding/md)
│   │   Width: 100%
│   │
│   │   Header row:
│   │   │ "Category" | "In-App" | "Email" | "SMS"
│   │   │ Column widths: 40% | 20% | 20% | 20%
│   │   │ Header BG: color/background
│   │   │ Font: Label/Base
│   │
│   │   Data rows:
│   │   Each row:
│   │   ├── Height: 56px
│   │   ├── Padding: 0 16px
│   │   ├── Border-bottom: 1px color/divider
│   │   │
│   │   ├── Category name (Body/SM, Medium)
│   │   │   ├── Academic Updates
│   │   │   ├── Financial / Invoices
│   │   │   ├── Attendance Warnings
│   │   │   ├── Achievements / Gamification
│   │   │   └── System Announcements
│   │   │
│   │   └── Toggles (RP/Toggle, md)
│   │       In-App: Always ON (disabled, can't turn off)
│   │       Email: ON/OFF toggle
│   │       SMS: ON/OFF toggle
│   │
│   │   In-App column: Lock icon + "Always on" (Body/XS, muted)
│   │
│   ├── DIGEST SETTINGS
│   │   RP/Card (padding/md)
│   │   Layout: Vertical, gap 16px
│   │
│   │   ├── H5: "Digest Settings"
│   │   ├── Body/SM: "Receive a summary of notifications instead of individual alerts."
│   │   │
│   │   ├── RP/Select (md)
│   │   │   Label: "Digest Frequency"
│   │   │   Options: None / Daily / Weekly
│   │   │
│   │   └── RP/Input (time, md)
│   │       Label: "Preferred Time"
│   │       Value: "08:00"
│   │       (Only shown if frequency != None)
│   │
│   └── SAVE
│       RP/Button (primary, lg): "Save Preferences"
│       Success toast: "Preferences saved ✓"
│
└── Bottom padding: 48px
```

---

## STU-19: STUDENT PROFILE

### Frame: `RP/Student/STU-19-Profile`

### Desktop Light

```
Frame: STU-19-Profile-Desktop-Light
Width: 1440px
BG: color/background

├── RP/Sidebar (student, active: profile)
├── RP/Topbar (student)
│
├── Content Area
│   Max-width: 720px (centered)
│   Padding: 24px
│   Layout: Vertical, gap 24px
│
│   ├── Page Header
│   │   ├── H1: "My Profile"
│   │   └── Breadcrumb: "Dashboard > Profile"
│   │
│   ├── PROFILE HEADER
│   │   RP/Card (shadow/sm, padding/lg)
│   │   Layout: Horizontal, gap 24px, alignment: center
│   │
│   │   ├── RP/Avatar (lg, has-image)
│   │   │   Diameter: 80px
│   │   │   [Change Photo] overlay on hover
│   │   │
│   │   ├── Profile Info
│   │   │   ├── Name: "Amara Asante" (Display/H4)
│   │   │   ├── Student ID: "RP-2026-00001" (Mono/Base)
│   │   │   ├── Class: "JSS 2" (Body/Base)
│   │   │   └── Status: RP/Badge (success): "Active"
│   │   │
│   │   └── Tier + Streak (right-aligned)
│   │       ├── RP/TierBadge (silver, highlighted)
│   │       └── RP/StreakBadge (md): 🔥 12 days
│   │
│   ├── PERSONAL INFORMATION
│   │   RP/Card (padding/md)
│   │   Layout: Vertical, gap 16px
│   │
│   │   ├── H5: "Personal Information"
│   │   │
│   │   └── Info Grid (2 columns)
│   │       Each field:
│   │       ├── Label (Body/XS, muted)
│   │       └── Value (Body/Base)
│   │
│   │       ├── Full Name: "Amara Asante"
│   │       ├── Date of Birth: "March 15, 2012"
│   │       ├── Gender: "Female"
│   │       ├── Email: "amara@email.com"
│   │       └── Phone: "+233 XX XXX XXXX"
│   │
│   │   [Edit Profile] button → modal with editable fields
│   │
│   ├── CREDENTIALS
│   │   RP/Card (padding/md)
│   │   Layout: Vertical, gap 12px
│   │
│   │   ├── H5: "Credentials"
│   │   │
│   │   ├── RP/CredentialCard (revealed: false)
│   │   │   Student ID + Password with toggle + copy
│   │   │   Same as REG-04 but embedded
│   │
│   │   └── RP/Button (ghost, sm): "Change Password"
│   │       → Modal: Current password + New password + Confirm
│   │
│   ├── ENROLLMENT INFO
│   │   RP/Card (padding/md)
│   │   Layout: Vertical, gap 12px
│   │
│   │   ├── H5: "Enrollment"
│   │   ├── Academic Year: "2025/2026"
│   │   ├── Class: "JSS 2"
│   │   ├── Enrolled: "September 5, 2025"
│   │   └── Guardian: "Kofi Asante (Primary)"
│   │
│   └── SETTINGS LINKS
│       RP/Card (padding/md)
│       Layout: Vertical, gap 0
│
│       ├── RP/Button (ghost, full-width, justify: start)
│       │   Icon: bell (20px)
│       │   "Notification Preferences"
│       │   → STU-18
│       │
│       ├── RP/Button (ghost, full-width, justify: start)
│       │   Icon: palette (20px)
│       │   "Appearance Settings"
│       │   → Theme toggle (light/dark/system)
│       │
│       └── RP/Button (ghost, full-width, justify: start, danger)
│           Icon: log-out (20px)
│           "Logout"
│           → Confirm modal
│
└── Bottom padding: 48px
```

---

## PROTOTYPE INTERACTIONS — Student Portal

| Step | Screen | Trigger | Action |
|------|--------|---------|--------|
| 1 | STU-01 | Click subject card | → STU-02 (OPS Breakdown filtered) |
| 2 | STU-01 | Click deadline item | → STU-07 (Assignment Detail) |
| 3 | STU-01 | Click "View All" badges | → STU-14 (Achievements) |
| 4 | STU-01 | Click leaderboard row | → STU-15 (Full Leaderboard) |
| 5 | STU-04 | Click "Join Session" | → STU-05 (Live Classroom) |
| 6 | STU-05 | Click "Leave" | → STU-04 (Session Detail) |
| 7 | STU-06 | Click "Start" on assignment | → STU-07 |
| 8 | STU-08 | Click "Start Exam" | → STU-09 |
| 9 | STU-09 | Click "Submit" | → STU-10 (Result) |
| 10 | STU-10 | Click "Retry" | → STU-09 |
| 11 | STU-14 | Click badge | → Badge detail tooltip |
| 12 | STU-17 | Click notification | → Navigate to context |