UTS Phase 22.5 — Flutter guide lightbox LEARN mode + behavior
Status: Ready (grounded 2026-07-02) · Depends on: 22.1 tokens, 22.2 atoms, 22.3 blocks, 22.4 shell+cook (11846f2e). Scope: the guide lightbox LEARN mode (course guides) — the last piece of the UTS Flutter parity track. Web is the authoritative reference (kon_guide_v2.css / _guide_lightbox.gohtml / guide-lightbox.js); the behavior target is the Phase-20 contract (phase-20-learn-completion-review.md, D20.1–D20.6), which the Flutter track "must mirror."
⚠️ 22.5 has TWO contracts running together: (A) VISUAL — restyle the 4 learn surfaces onto
g-*(they currently render on legacyguideLightbox*tokens = the "mixed state" 22.4 left intentional); (B) BEHAVIOR — the Phase-20 nonsequential/honest-completion flip. Do NOT restyle a surface without also landing its behavior slice, or you get a pretty-but-wrong end page.
Method & rigor (lessons applied — read before trusting the surface/behavior sections below)
The surface + behavior descriptions in THIS doc are grep-grounded, not code-grounded — i.e. UNVERIFIED assumptions about the current Flutter learn state. The 22.3 lesson (an assumption-audit that confirms fields exist still missed the render structure) and the CLAUDE.md "don't assume then certify" rule both say misses hide exactly here. So 22.5 does NOT start by building:
- Step 0 (MANDATORY, before any build) = a measured current-state + delta audit of the 5 learn files against BOTH contracts. Same method that worked in 22.4 (property-level, source-grounded): for each learn surface, read the actual Flutter file AND the web CSS/template/JS, enumerate every property/behavior, and classify MATCH / DIVERGE / DEAD / MISSING — for the VISUAL contract (vs
kon_guide_v2.css) AND the BEHAVIOR contract (vs the Phase-20 D20.1–D20.6 points: which are ALREADY satisfied in Flutter vs missing). Write the delta tophase-22.5-learn-parity-audit.md. The build steps then target the MEASURED diverges — not this doc's assumptions. Confidence % must be earned from that measured set. - Per-surface done-gate = a property-level re-check vs source, THEN the eyeball smoke — NOT eyeball alone. 22.4 proved eyeballing misses systematic issues (the property audit caught 3 of my own misses the smoke would not have). A surface isn't "done" until its measured diverges are all closed on a clean re-run.
- Verify load-bearing claims in code. Any claim that drives a decision (e.g. "canAdvance gates Next", "completion is presence-based") gets re-read at its
file:linebefore it's acted on — the way the disc-glyph and canAdvance claims were re-verified this session. - 22.5 is FLUTTER-ONLY — NO backend / ent / schema change. The learn behavior (nonsequential, honest completion, resume) is computed CLIENT-SIDE from hydrated per-step state (Phase-20/21); the backend is unchanged and
current_step_indexstays vestigial (Phase-21 D21.2). If a "fix" seems to need a backend change, that's the signal to STOP (the ent-schema catch from 22.4) — align Flutter to the existing contract instead. - Dead tokens retired by hand (no scripts), rule = "0 refs outside design_tokens.dart", only as each surface actually moves to
g-*.
What's already done (don't redo)
- Shell (barrier/panel/close), masthead (
GuideBand), metadata (GuideMetadataGrid), materials (flatMaterialRow) — all built in 22.4 as SHARED widgets. Learn's overview must ADOPTGuideBand+GuideMetadataGrid(it still renders the old cover/title/badge/stat + its own metadata grid). - Answer-row atom —
guide_lightbox_lesson_page.dartalready usesAnswerOptionRow(lightbox:true)+ verdict_optionState+ centered brand "Submit Answer" (pulled forward in 22.4, smoked on the Mixology quiz). The rest of the lesson page (header/counter/title/body/Mark-Complete) is still legacy. - Bloc — learn events exist (
GuideProgressPageChanged/ReviewEntered/ReviewExited);resumePage(first-incomplete, client-computed) exists; the#6hydration fix + shared reset all apply.
Surfaces (current Flutter file → web target)
- Overview (
guide_lightbox_overview.dart, 522 lines) — web.o-guide-lightbox-page[data-guide-page=0]:GuideBandmasthead +GuideMetadataGrid(ADOPT) · About (.o-guide-lightbox-overview-about) · objective callout (.o-guide-lightbox-overview-objective, "What you'll learn") · materials (already shared) · adaptive CTA (.o-guide-lightbox-overview-start: Start/Continue/Review +{N} lessonscount) · scroll hint. Currently blue COURSE/BEGINNER badges + blue objective box + old cover/title = all legacy. - Lesson pages (
guide_lightbox_lesson_page.dart, 502) — web.o-guide-lightbox-lesson-*: counter (Lesson N of M) · title · body (15/1.6/g-body) · qtype label · question (answer-row DONE) ·Mark Completebutton (.o-guide-lightbox-lesson-action,data-guide-lesson-complete). Restyle counter/title/body/qtype/mark-complete ontog-*. - Completion (
guide_lightbox_completion.dart, 132) — web.o-guide-lightbox-completion(data-guide-completion): trophy icon · title · score · Continue + Review All Lessons + Done. This is where the Phase-20 D20.1/D20.2/D20.5 behavior lives. - Review (
guide_lightbox_review.dart, 355) — web.o-guide-lightbox-review(separate DOM): per-lesson review rows (number disc, correct/incorrect, answer label, explanation). Restyle ontog-*(discs →StepDiscfamily colours). - Footer nav (
guide_lightbox_footer.dartlearn branch_buildLearnFooter/_navButton/_buildReviewFooter) — prev/next nav buttons + learn progress fill (currently blueguideLightboxProgressFillLearn→ g-ok green, web:387-388) + review "Exit Review" footer.