Files
967e81d33f docs(prd): learner-first mobile app PRD and interactive prototypes (#916)
* docs(prd): add learner-first mobile app PRD and interactive prototypes

Draft the ClassroomIO iOS/Android companion as a learner-first product
(attention home, compliance wallet, offline content, push on top of
prd/notification-system) with clickable HTML prototypes as the UX source
of truth.

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

* style(prd): quiet mobile app prototype colours to match @cio/ui

Replace filled red/orange/green surfaces with the dashboard Badge and Alert recipes: 10% tint chips, card-background alerts, and default rows. Keep destructive fills only for actual destroy actions.

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
2026-08-18 12:02:35 +01:00

330 lines
19 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Learn — ClassroomIO Mobile</title>
<link href="https://fonts.googleapis.com/css2?family=Geist:wght@300..800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="app-theme.css" />
<script>
if (localStorage.cioTheme === 'dark' || (!localStorage.cioTheme && matchMedia('(prefers-color-scheme: dark)').matches))
document.documentElement.classList.add('dark');
</script>
</head>
<body>
<header class="proto-head">
<a class="back" href="index.html"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" width="14" height="14"><path d="m15 18-6-6 6-6"/></svg> All screens</a>
<span class="eyebrow">Learner · Tab 2</span>
<h1>Learn — my learning, explore, cohorts</h1>
<p>
Everything the learner is enrolled in, everything the organization has published, and the cohorts they belong to.
Course rows carry a progress ring, a type chip (Compliance / Cohort / Self-paced), and a download marker.
Explore enrolls in place for assigned and free courses — there is deliberately no checkout anywhere in the app.
</p>
<div class="proto-links">
<a href="course.html">Course detail →</a>
<a href="downloads.html">Downloads →</a>
<a href="home.html">← Home</a>
</div>
</header>
<div class="stage">
<!-- 1. MY LEARNING -->
<figure class="device">
<div class="phone">
<div class="phone-inner">
<div class="notch"></div>
<div class="statusbar" data-status="9:41"></div>
<div class="navbar">
<div class="title">Learn</div>
<div class="actions">
<button class="icon-btn" aria-label="Search"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg></button>
<a class="icon-btn" href="downloads.html" aria-label="Downloads"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 15V3M7 10l5 5 5-5"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/></svg></a>
</div>
</div>
<div class="tabs" data-select>
<button class="on" data-option>My learning</button>
<button data-option>Explore</button>
<button data-option>Cohorts</button>
</div>
<div class="screen">
<div class="segmented" data-select style="margin: 12px 0 14px">
<button class="on" data-option>In progress</button>
<button data-option>Not started</button>
<button data-option>Completed</button>
</div>
<div class="stack">
<a class="lrow current" href="course.html">
<div class="ring">
<svg viewBox="0 0 36 36"><circle class="track" cx="18" cy="18" r="15.5" fill="none" stroke-width="3.4"/><circle class="arc primary" cx="18" cy="18" r="15.5" fill="none" stroke-width="3.4" stroke-linecap="round" stroke-dasharray="97.4" stroke-dashoffset="65.3"/></svg>
<span class="lbl tnum">33%</span>
</div>
<div class="grow">
<div class="ltitle">Forklift Safety Recertification 2026</div>
<div class="lmeta">
<span class="badge badge-danger-soft">Overdue</span>
<span class="badge badge-outline">Compliance</span>
</div>
<div class="lmeta">
<span class="dl-dot"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5"/></svg></span>
<span>Downloaded</span><span class="sep">·</span><span>Lesson 4 of 12</span>
</div>
</div>
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m9 18 6-6-6-6"/></svg></span>
</a>
<a class="lrow" href="course.html">
<div class="ring">
<svg viewBox="0 0 36 36"><circle class="track" cx="18" cy="18" r="15.5" fill="none" stroke-width="3.4"/><circle class="arc primary" cx="18" cy="18" r="15.5" fill="none" stroke-width="3.4" stroke-linecap="round" stroke-dasharray="97.4" stroke-dashoffset="73.1"/></svg>
<span class="lbl tnum">25%</span>
</div>
<div class="grow">
<div class="ltitle">Warehouse Fire Safety</div>
<div class="lmeta"><span class="badge badge-warning-soft">Due in 6 days</span><span class="badge badge-outline">Compliance</span></div>
<div class="lmeta">
<span class="dl-dot"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5"/></svg></span>
<span>Downloaded</span><span class="sep">·</span><span>2 of 8 lessons</span>
</div>
</div>
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m9 18 6-6-6-6"/></svg></span>
</a>
<a class="lrow" href="course.html">
<div class="ring">
<svg viewBox="0 0 36 36"><circle class="track" cx="18" cy="18" r="15.5" fill="none" stroke-width="3.4"/><circle class="arc primary" cx="18" cy="18" r="15.5" fill="none" stroke-width="3.4" stroke-linecap="round" stroke-dasharray="97.4" stroke-dashoffset="29.2"/></svg>
<span class="lbl tnum">70%</span>
</div>
<div class="grow">
<div class="ltitle">Data Protection &amp; GDPR Essentials</div>
<div class="lmeta"><span class="badge badge-outline">Cohort</span><span>Q3 Frontline Onboarding</span></div>
<div class="lmeta"><span>Knowledge check due in 2 days</span></div>
</div>
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m9 18 6-6-6-6"/></svg></span>
</a>
<a class="lrow" href="course.html">
<div class="ring">
<svg viewBox="0 0 36 36"><circle class="track" cx="18" cy="18" r="15.5" fill="none" stroke-width="3.4"/><circle class="arc primary" cx="18" cy="18" r="15.5" fill="none" stroke-width="3.4" stroke-linecap="round" stroke-dasharray="97.4" stroke-dashoffset="88.6"/></svg>
<span class="lbl tnum">9%</span>
</div>
<div class="grow">
<div class="ltitle">Customer Service Excellence</div>
<div class="lmeta"><span class="badge badge-outline">Self-paced</span><span>Optional</span></div>
</div>
<span class="chev"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m9 18 6-6-6-6"/></svg></span>
</a>
</div>
</div>
<nav class="tabbar" data-tabbar="learn"></nav>
<div class="home-bar"></div>
</div>
</div>
<figcaption><b>My learning</b>Progress ring, urgency badge, course type, and download state on every row — the four things a learner scans for.</figcaption>
</figure>
<!-- 2. EXPLORE -->
<figure class="device">
<div class="phone">
<div class="phone-inner">
<div class="notch"></div>
<div class="statusbar" data-status="9:41"></div>
<div class="navbar">
<div class="title">Learn</div>
<div class="actions">
<button class="icon-btn" aria-label="Search"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg></button>
<a class="icon-btn" href="downloads.html" aria-label="Downloads"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 15V3M7 10l5 5 5-5"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/></svg></a>
</div>
</div>
<div class="tabs" data-select>
<button data-option>My learning</button>
<button class="on" data-option>Explore</button>
<button data-option>Cohorts</button>
</div>
<div class="screen">
<div class="search" style="margin: 12px 0 12px">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>
Search Northwind Academy
</div>
<div class="chips" data-select style="margin-bottom: 14px">
<button class="chip on" data-option>All</button>
<button class="chip" data-option>Safety</button>
<button class="chip" data-option>Compliance</button>
<button class="chip" data-option>Operations</button>
<button class="chip" data-option>Soft skills</button>
</div>
<div class="stack">
<div class="card" style="overflow: hidden">
<div style="height: 96px; background: linear-gradient(135deg, oklch(0.488 0.243 264.376), oklch(0.424 0.199 265.638)); position: relative">
<span class="badge badge-secondary" style="position: absolute; top: 10px; left: 10px">Safety</span>
</div>
<div class="card-pad">
<div class="ltitle" style="font-size: 15px">Hazardous Materials Handling</div>
<div class="lsub">Segregation, spill response, and documentation for warehouse teams.</div>
<div class="lmeta"><span>8 lessons</span><span class="sep">·</span><span>~45 min</span><span class="sep">·</span><span>Certificate</span></div>
<div class="row" style="margin-top: 12px">
<span class="badge badge-primary-soft">Assigned to you</span>
<button class="btn btn-primary btn-sm" style="margin-left: auto">Start</button>
</div>
</div>
</div>
<a class="lrow" href="course.html">
<div class="media sq" style="background: linear-gradient(135deg, oklch(0.488 0.243 264.376), oklch(0.424 0.199 265.638)); border: none; color: #fff">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>
</div>
<div class="grow">
<div class="ltitle">Manual Handling &amp; Ergonomics</div>
<div class="lmeta"><span>6 lessons</span><span class="sep">·</span><span>~25 min</span></div>
</div>
<button class="btn btn-outline btn-sm">Enroll</button>
</a>
<a class="lrow" href="course.html">
<div class="media sq" style="background: linear-gradient(135deg, oklch(0.546 0.245 262.881), oklch(0.488 0.243 264.376)); border: none; color: #fff">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>
</div>
<div class="grow">
<div class="ltitle">Working at Height</div>
<div class="lmeta"><span>5 lessons</span><span class="sep">·</span><span>~20 min</span></div>
</div>
<button class="btn btn-outline btn-sm">Enroll</button>
</a>
<a class="lrow" href="course.html">
<div class="media sq" style="background: linear-gradient(135deg, oklch(0.685 0.169 237.323), oklch(0.424 0.199 265.638)); border: none; color: #fff">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>
</div>
<div class="grow">
<div class="ltitle">Difficult Conversations</div>
<div class="lmeta"><span>4 lessons</span><span class="sep">·</span><span>~18 min</span></div>
</div>
<button class="btn btn-outline btn-sm">Enroll</button>
</a>
</div>
<div class="banner banner-muted" style="margin-top: 16px">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4M12 8h.01"/></svg>
<div class="bd" style="color: var(--muted-foreground)">
Paid enrollment is handled by your organization on the web — the app never asks for payment.
</div>
</div>
</div>
<nav class="tabbar" data-tabbar="learn"></nav>
<div class="home-bar"></div>
</div>
</div>
<figcaption><b>Explore</b>The org catalog with enroll-in-place. No checkout, no upgrade prompt, no external purchase link — Decision 9 in the PRD.</figcaption>
</figure>
<!-- 3. COHORTS -->
<figure class="device">
<div class="phone">
<div class="phone-inner">
<div class="notch"></div>
<div class="statusbar" data-status="9:41"></div>
<div class="navbar">
<div class="title">Learn</div>
<div class="actions">
<button class="icon-btn" aria-label="Search"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg></button>
<a class="icon-btn" href="downloads.html" aria-label="Downloads"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 15V3M7 10l5 5 5-5"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/></svg></a>
</div>
</div>
<div class="tabs" data-select>
<button data-option>My learning</button>
<button data-option>Explore</button>
<button class="on" data-option>Cohorts</button>
</div>
<div class="screen">
<div class="card card-pad" style="margin: 12px 0 10px">
<div class="row between">
<div>
<div class="ltitle" style="font-size: 15px">Q3 Frontline Onboarding</div>
<div class="lsub">18 members · Daniel Mensah</div>
</div>
<span class="badge badge-success-soft">Active</span>
</div>
<div class="divider"></div>
<div class="eyebrow" style="margin-bottom: 8px">Cohort goal</div>
<div class="row">
<div class="progress tall success"><span style="width: 72%"></span></div>
<span class="tnum" style="font-size: 12px; font-weight: 600">13/18</span>
</div>
<div class="lmeta"><span>Everyone completes GDPR Essentials by 30 Aug · 9 days left</span></div>
<div class="divider"></div>
<div class="eyebrow" style="margin-bottom: 8px">Your progress</div>
<div class="stack-sm stack">
<div class="row">
<span class="dl-dot"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5"/></svg></span>
<span style="font-size: 13px">Welcome &amp; expectations</span>
</div>
<div class="row">
<span class="dl-dot"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5"/></svg></span>
<span style="font-size: 13px">Site induction</span>
</div>
<div class="row">
<span class="media" style="width: 16px; height: 16px; border-radius: 999px"></span>
<span style="font-size: 13px" class="text-muted">GDPR Essentials — knowledge check</span>
</div>
</div>
<a class="btn btn-outline btn-block btn-sm" href="course.html" style="margin-top: 14px; height: 36px">Open cohort course</a>
</div>
<div class="sec-head"><h2>Upcoming sessions</h2></div>
<div class="stack">
<div class="lrow">
<div class="media is-current"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg></div>
<div class="grow">
<div class="ltitle">Practical forklift assessment</div>
<div class="lmeta"><span>Thu 21 Aug · 14:00</span><span class="sep">·</span><span>Bay 4</span></div>
</div>
<span class="badge badge-outline">In person</span>
</div>
<div class="lrow">
<div class="media"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m22 8-6 4 6 4V8z"/><rect x="2" y="6" width="14" height="12" rx="2"/></svg></div>
<div class="grow">
<div class="ltitle">GDPR Q&amp;A with Daniel</div>
<div class="lmeta"><span>Fri 22 Aug · 10:00</span><span class="sep">·</span><span>Live class</span></div>
</div>
<button class="btn btn-outline btn-sm">Join</button>
</div>
</div>
<div class="hint" style="margin-top: 12px">
Live classes open in your organization's meeting provider — the app doesn't host video conferencing.
</div>
</div>
<nav class="tabbar" data-tabbar="learn"></nav>
<div class="home-bar"></div>
</div>
</div>
<figcaption><b>Cohorts</b>Goal progress, the learner's own checklist, and upcoming sessions. Live classes hand off to the org's existing provider.</figcaption>
</figure>
</div>
<button class="theme-toggle" title="Toggle theme" aria-label="Toggle theme">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/></svg>
</button>
<script src="proto.js"></script>
</body>
</html>