Files

325 lines
20 KiB
HTML
Raw Permalink Normal View History

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Lesson player — 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 · Player</span>
<h1>Lesson player</h1>
<p>
HLS video with captions, speed, PiP, background audio, and lock-screen controls, authorized by the new
<code>GET /hls/:assetId/playback-token</code> because a native player can't carry the web's per-asset cookie.
Transcript and the AI Lesson Tutor are bottom sheets over the same screen; mark-complete queues locally when offline.
</p>
<div class="proto-links">
<a href="course.html">← Course outline</a>
<a href="exercise.html">Next: knowledge check →</a>
<a href="downloads.html">Sync queue →</a>
</div>
</header>
<div class="stage">
<!-- 1. ONLINE PLAYER -->
<figure class="device">
<div class="phone">
<div class="phone-inner">
<div class="notch"></div>
<div class="statusbar" data-status="9:46"></div>
<div class="navbar">
<a class="icon-btn plain" href="course.html" aria-label="Back"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m15 18-6-6 6-6"/></svg></a>
<div class="grow">
<div class="sub">Section 2 · Lesson 4 of 12</div>
<div class="title-sm">Pre-operation inspection</div>
</div>
<button class="icon-btn" aria-label="Lesson language"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20"/></svg></button>
</div>
<div class="screen">
<div class="player">
<span class="pill"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5"/></svg> Downloaded</span>
<div class="play"><svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M8 5v14l11-7z"/></svg></div>
<div class="ctrl">
<div class="bar"><span style="width: 34%"></span></div>
<div class="meta">
<span>3:04</span>
<span style="opacity: 0.7">9:12</span>
<span class="right">
<span style="font-weight: 600">1.25x</span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="2" y="5" width="20" height="14" rx="2"/><path d="M7 15h4M14 15h3"/></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M5 17H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v3"/><rect x="12" y="13" width="10" height="7" rx="2"/></svg>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M8 3H5a2 2 0 0 0-2 2v3M16 3h3a2 2 0 0 1 2 2v3M8 21H5a2 2 0 0 1-2-2v-3M16 21h3a2 2 0 0 0 2-2v-3"/></svg>
</span>
</div>
</div>
</div>
<div class="row" style="margin: 12px 0 6px">
<div class="segs">
<span class="seg done"></span><span class="seg done"></span><span class="seg done"></span><span class="seg now"></span>
<span class="seg"></span><span class="seg"></span><span class="seg"></span><span class="seg"></span>
<span class="seg"></span><span class="seg"></span><span class="seg"></span><span class="seg"></span>
</div>
<span class="text-muted tnum" style="font-size: 11.5px">4/12</span>
</div>
<h2 style="font-size: 18px; font-weight: 600; letter-spacing: -0.02em; margin: 10px 0 8px">
Pre-operation inspection checklist
</h2>
<div class="row" style="margin-bottom: 12px; gap: 6px; flex-wrap: wrap">
<span class="badge badge-outline">Video · 9 min</span>
<span class="badge badge-outline">English</span>
<span class="badge badge-success-soft">Available offline</span>
</div>
<div class="prose">
<p>
A pre-operation inspection takes about four minutes and catches most of the faults that cause workplace
incidents. Work through it in the same order every time so nothing gets skipped when you're in a hurry.
</p>
<h3>The seven checks</h3>
<ul>
<li><strong>Tyres and wheels</strong> — cuts, embedded debris, correct pressure.</li>
<li><strong>Forks</strong> — cracks at the heel, bent tips, locking pins seated.</li>
<li><strong>Hydraulic hoses</strong> — chafing, weeping seals, pooled fluid underneath.</li>
<li><strong>Mast and chains</strong> — even tension, no kinked links.</li>
<li><strong>Horn, lights, and alarm</strong> — audible and visible from 10 metres.</li>
<li><strong>Data plate</strong> — legible, and the rated capacity matches today's load.</li>
<li><strong>Seatbelt</strong> — retracts cleanly and latches.</li>
</ul>
<p>Log the result before you move the truck. An unlogged inspection counts as no inspection.</p>
</div>
<div class="stack" style="margin: 16px 0 12px">
<button class="lrow" data-sheet-open="transcript" style="width: 100%; text-align: left; cursor: pointer">
<div class="media"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6M8 13h8M8 17h5"/></svg></div>
<div class="grow"><div class="ltitle">Transcript</div><div class="lsub">Tap a line to jump to that moment</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>
</button>
<button class="lrow" data-sheet-open="tutor" style="width: 100%; text-align: left; cursor: pointer">
<div class="media is-current"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m12 3 1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9z"/></svg></div>
<div class="grow"><div class="ltitle">Ask the AI tutor</div><div class="lsub">Answers from this lesson only · 8 of 20 questions left today</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>
</button>
</div>
<div class="divider"></div>
<a class="btn btn-primary btn-lg btn-block" href="lesson.html">
Mark complete &amp; continue
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m9 18 6-6-6-6"/></svg>
</a>
<div class="hint" style="text-align: center">Next: Load stability and centre of gravity · 7 min</div>
</div>
<div class="scrim" data-scrim-for="transcript" style="display: none"></div>
<div class="sheet" id="transcript" style="display: none">
<div class="grabber"></div>
<div class="sheet-head">
<div class="st">Transcript</div>
<button class="icon-btn plain" data-sheet-close="transcript" style="margin-left: auto" aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
</div>
<div class="sheet-body">
<div class="lrow flat"><span class="text-muted tnum" style="font-size: 11.5px; width: 34px">0:12</span><div class="grow"><div style="font-size: 13.5px">Before you touch the controls, walk the truck. Start at the front-left tyre.</div></div></div>
<div class="lrow flat" style="background: color-mix(in oklab, var(--primary) 8%, transparent); border-radius: var(--radius-md); padding: 11px 8px">
<span class="text-primary tnum" style="font-size: 11.5px; width: 34px; font-weight: 600">3:04</span>
<div class="grow"><div style="font-size: 13.5px; font-weight: 500">Look for weeping seals — a wet film on the ram is a fault, not a maybe.</div></div>
</div>
<div class="lrow flat"><span class="text-muted tnum" style="font-size: 11.5px; width: 34px">3:41</span><div class="grow"><div style="font-size: 13.5px">Chains should have even tension. If one side sags, tag the truck out.</div></div></div>
<div class="lrow flat"><span class="text-muted tnum" style="font-size: 11.5px; width: 34px">4:18</span><div class="grow"><div style="font-size: 13.5px">The data plate tells you the rated capacity at a given load centre.</div></div></div>
<div class="lrow flat"><span class="text-muted tnum" style="font-size: 11.5px; width: 34px">5:02</span><div class="grow"><div style="font-size: 13.5px">Finally, the seatbelt. It has to retract cleanly and latch first time.</div></div></div>
</div>
</div>
<div class="scrim" data-scrim-for="tutor" style="display: none"></div>
<div class="sheet" id="tutor" style="display: none">
<div class="grabber"></div>
<div class="sheet-head">
<div class="media is-current" style="width: 30px; height: 30px"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m12 3 1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9z"/></svg></div>
<div><div class="st">AI lesson tutor</div><div class="lsub" style="margin: 0">Scoped to this lesson</div></div>
<button class="icon-btn plain" data-sheet-close="tutor" style="margin-left: auto" aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
</div>
<div class="sheet-body">
<div style="display: flex; justify-content: flex-end; margin-bottom: 10px">
<div style="max-width: 78%; background: var(--primary); color: var(--primary-foreground); padding: 9px 12px; border-radius: 16px 16px 4px 16px; font-size: 13.5px">
What counts as a "weeping" seal versus normal residue?
</div>
</div>
<div style="display: flex; gap: 8px; margin-bottom: 12px">
<div class="media is-current" style="width: 26px; height: 26px"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m12 3 1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9z"/></svg></div>
<div style="max-width: 82%; background: var(--muted); padding: 9px 12px; border-radius: 16px 16px 16px 4px; font-size: 13.5px; line-height: 1.5">
Residue is dry and dull — old dust bonded to grease. Weeping is a wet, shiny film that reappears after you
wipe it. This lesson's rule at 3:04: if it comes back, tag the truck out.
<div class="lmeta" style="margin-top: 7px"><span class="badge badge-outline">From 3:04</span></div>
</div>
</div>
<div class="row" style="gap: 8px">
<input class="input" placeholder="Ask about this lesson…" />
<button class="icon-btn" style="width: 40px; height: 40px" aria-label="Send"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m22 2-7 20-4-9-9-4z"/></svg></button>
</div>
<div class="hint">8 of 20 questions left today · resets at midnight</div>
</div>
</div>
<div class="home-bar"></div>
</div>
</div>
<figcaption><b>Online player</b>Video, native prose, and two sheets (transcript, AI tutor) — tap either row in the live prototype to open it.</figcaption>
</figure>
<!-- 2. AI TUTOR CAP -->
<figure class="device">
<div class="phone">
<div class="phone-inner">
<div class="notch"></div>
<div class="statusbar" data-status="21:18"></div>
<div class="navbar">
<a class="icon-btn plain" href="course.html" aria-label="Back"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m15 18-6-6 6-6"/></svg></a>
<div class="grow">
<div class="sub">Section 2 · Lesson 5 of 12</div>
<div class="title-sm">Load stability</div>
</div>
</div>
<div class="screen">
<div class="player">
<div class="play"><svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M8 5v14l11-7z"/></svg></div>
<div class="ctrl">
<div class="bar"><span style="width: 88%"></span></div>
<div class="meta"><span>6:11</span><span style="opacity: 0.7">7:02</span></div>
</div>
</div>
<div class="prose" style="margin-top: 14px">
<p>
The load centre is the horizontal distance from the fork face to the load's centre of gravity. Every truck's
data plate is rated at a specific load centre — usually 500 mm.
</p>
</div>
</div>
<div class="scrim"></div>
<div class="sheet" style="display: flex">
<div class="grabber"></div>
<div class="sheet-head">
<div class="media is-current" style="width: 30px; height: 30px"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m12 3 1.9 5.1L19 10l-5.1 1.9L12 17l-1.9-5.1L5 10l5.1-1.9z"/></svg></div>
<div><div class="st">AI lesson tutor</div><div class="lsub" style="margin: 0">Scoped to this lesson</div></div>
<button class="icon-btn plain" style="margin-left: auto" aria-label="Close"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M18 6 6 18M6 6l12 12"/></svg></button>
</div>
<div class="sheet-body">
<div class="empty" style="padding: 22px 12px 16px">
<div class="ei">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
</div>
<div class="et">You've used today's 20 questions</div>
<div class="ed">Your allowance resets at midnight. The transcript and lesson notes are still available.</div>
</div>
<button class="btn btn-outline btn-block">Open transcript instead</button>
<button class="btn btn-ghost btn-block" style="margin-top: 6px">Ask in Community</button>
<div class="hint" style="text-align: center; margin-top: 10px">
Fair-use caps are set by your organization.
</div>
</div>
</div>
<div class="home-bar"></div>
</div>
</div>
<figcaption><b>AI tutor, cap reached</b>The fair-use limit is stated plainly with two real alternatives, not a paywall — the app never sells token packs.</figcaption>
</figure>
<!-- 3. OFFLINE / QUEUED -->
<figure class="device">
<div class="phone">
<div class="phone-inner">
<div class="notch"></div>
<div class="statusbar" data-status="18:40" data-offline></div>
<div class="offline-strip">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M2 2 22 22M8.5 16.5a5 5 0 0 1 7 0M5 13a10 10 0 0 1 4-2.4M12 20h.01"/></svg>
Offline — progress will sync automatically
</div>
<div class="navbar">
<a class="icon-btn plain" href="course.html" aria-label="Back"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m15 18-6-6 6-6"/></svg></a>
<div class="grow">
<div class="sub">Section 2 · Lesson 5 of 12</div>
<div class="title-sm">Load stability</div>
</div>
</div>
<div class="screen">
<div class="player">
<span class="pill"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5"/></svg> Playing from device</span>
<div class="play"><svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M6 4h4v16H6zM14 4h4v16h-4z"/></svg></div>
<div class="ctrl">
<div class="bar"><span style="width: 100%"></span></div>
<div class="meta"><span>7:02</span><span style="opacity: 0.7">7:02</span></div>
</div>
</div>
<div class="banner banner-muted" style="margin: 14px 0 12px">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 6 9 17l-5-5"/></svg>
<div class="grow">
<div class="bt">Marked complete</div>
<div class="bd">Saved on this device · will sync when you're back online</div>
</div>
</div>
<div class="sec-head" style="margin-top: 6px"><h2>Waiting to sync</h2><span class="count">2</span></div>
<div class="stack">
<div class="lrow">
<div class="media"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 12a9 9 0 1 1-6.2-8.6"/><path d="M21 3v6h-6"/></svg></div>
<div class="grow">
<div class="ltitle">Lesson 5 completed</div>
<div class="lmeta"><span>Queued 18:40</span></div>
</div>
<span class="badge badge-muted">Queued</span>
</div>
<div class="lrow">
<div class="media"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 12a9 9 0 1 1-6.2-8.6"/><path d="M21 3v6h-6"/></svg></div>
<div class="grow">
<div class="ltitle">Lesson 4 position 9:12</div>
<div class="lmeta"><span>Queued 18:31</span></div>
</div>
<span class="badge badge-muted">Queued</span>
</div>
</div>
<div class="divider"></div>
<a class="btn btn-primary btn-lg btn-block" href="lesson.html">
Next lesson
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="m9 18 6-6-6-6"/></svg>
</a>
<div class="lrow locked" style="margin-top: 10px">
<div class="media"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg></div>
<div class="grow">
<div class="ltitle">Section 2 check</div>
<div class="lsub">Exercises need a connection — we'll nudge you when you're back online</div>
</div>
</div>
</div>
<div class="home-bar"></div>
</div>
</div>
<figcaption><b>Offline &amp; queued</b>Completion is a monotonic, idempotent intent held on-device — the reason v1 offline covers content but not assessments.</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>