Skip to content

The practice list groups lessons by module and games by kind, collapsibly (10 Sep drop) #582

Description

@maximsan

This was generated by AI during triage.

Body rewritten at triage, 11 September 2026. Verified against prototype/screens.jsx at e914cf40 (LearnTab, SubGroup, PracticeGroup, ReplayRow). Re-reconciled 16 September 2026 against the 15 September drop (4beb98b2), which changed these same rows again — see What the 15 Sep drop changed below.

What the 15 Sep drop changed

Two things this ticket described are now stale, and the corrections are folded into the sections below.

  • Row meta is gone. ReplayRow no longer takes a meta at all: the ~N MIN on a lesson row and the ~2 MIN / FREE on a game row were all dropped. A row is its mark, its title, its eyebrow and its chevron.
  • Both dictionary drills read DICTIONARY as their eyebrow. FLIP AND RECALL and FROM THE DEFINITION are gone — the design's note: "FLIP AND RECALL restated the title's own mechanic." The eyebrow now says where the drill draws from, which is the one thing the title does not. The app still ships both old strings, as FlashcardsCopy.practiceRowEyebrow and VocabCopy.rowSubtitle.

Both drills carrying the same eyebrow means the two rows are no longer distinguishable by that text — check the entry-point tests, which currently assert each eyebrow resolves to exactly one widget.

Blocked by #596 since the 11 Sep drop (a16008c5): SubGroup and PracticeGroup are now the design's one Disclosure with site-specific slots (headerPad: '12px 0', minHeight: 44, glyph 16, trailing gap 14, panel paddingLeft: 34, paddingBottom: 4), so the sub-groups are built on that widget, not on their own chevron. The same drop dropped the PLACEHOLDER meta and derives a game's tier from FREE_LESSON_IDS, which is the app's rule already.

What the app draws now

Lessons is a flat list of every finished lesson, each row carrying a bean gauge and its module as the eyebrow. Games groups by kind under headings that do nothing — the kind's mark and name, no count, no lock, no chevron — with rows indented 30. No row tells Play from Replay. Keep Sharp's Start launches one chosen game or lesson.

What the design draws

The practice list keeps its two groups, Lessons and Games, and puts a second, collapsible level inside each.

  • Lessons: one sub-group per module the learner has finished lessons in, labelled MODULE n · LABEL with the module's glyph and the count. A lesson row loses its glyph and its module eyebrow — the sub-group header carries both now — and is its title alone, the ~N MIN having gone with the 15 Sep drop. Open by default only when there is a single module.
  • Games: the two dictionary drills first, as plain rows, keeping their own marks and both now reading DICTIONARY as their eyebrow; then one sub-group per kind, in the fixed kind order the app already uses, with the kind's mark, name and count. A kind with nothing open shows the lock mark and drops its label to opacity: 0.55. Closed by default.
  • A sub-group is a 44-high button: mark (20 wide), small-caps label, mono micro count, the lock when locked, a 16 chevron that turns 180° over 240ms; gap 14, padding 12px 0. Its children sit under paddingLeft: 34, paddingBottom: 4.
  • A row that starts something ends in a chevron and reads Play to assistive tech. A replay row keeps the replay arrow and reads Replay.
  • Keep Sharp's Start opens the matching group for the two types whose work lives in these lists — mini-games opens Games, lesson replay opens Lessons — rather than launching one item. The design's reason: "never a specific item — the rule, not the card, names the work". Vocab and Flashcards go on opening their own surfaces. Opening only, no scrolling: the design uses no scroll APIs either.
  • Opening the group is also what gives a Keep Sharp replay its confirm sheet. Every row in Lessons already raises it (#573, shipped), and Keep Sharp's direct launch is the one route left that skips it — Replaying a lesson skips the confirm sheet the design draws #573 registered that gap against this ticket. So it closes by itself here, as long as Start opens the group rather than keeping a shortcut that launches the lesson.

Rulings that beat the prototype

  • A sub-group is locked when every game in it fails the app's own open test. The prototype asks m.mod !== 'm1', which is the rule ADR-0007 forbids by name. Use the tier rule the catalog already uses.
  • A locked sub-group takes its screen-reader words from the locked-row copy register (ADR-0016), not a fresh literal.
  • Keep Sharp's acknowledgement needs no change. It is derived from the day's activity record and never from what Start launched, so opening a group still acknowledges once the type's own rule is met. Mini-games wants two different games in a day, which launching one game never satisfied anyway.

Acceptance criteria

  • Lessons collapse per module and Games per kind, each sub-group drawing its mark, count, lock and chevron as above, with the design's default-open rules
  • Game and drill rows end in a chevron and read Play; lesson rows keep the replay arrow, read Replay, and drop the glyph and module eyebrow their sub-group now carries
  • No row carries a meta, and both dictionary drills read DICTIONARY as their eyebrow
  • Keep Sharp's Start opens Games or Lessons for those two types and its own surface for the other two, and the day's acknowledgement still turns true when the type's rule is met — with a lesson replay reached this way raising Replaying a lesson skips the confirm sheet the design draws #573's confirm sheet, which the direct launch skips today
  • dart format, flutter analyze, the metrics gate and the suite pass, with a changelog bullet, and the list is shown in a screenshot

Out of scope

  • The PLACEHOLDER row meta. It is prototype authoring state: no app-side field carries it and no shipped content sets one. Moot since the 15 Sep drop, which removed row meta altogether.
  • The kind order and the kind labels, which already match.
  • The free-tier rule itself, and which games it opens.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    design-parityCloses a finding in the app-vs-prototype divergence registerfeature-buildA screen or mechanic the app does not have yetready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions