You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Body rewritten at triage, 11 September 2026. Verified against
prototype/screens.jsxate914cf40(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.
ReplayRowno longer takes ametaat all: the~N MINon a lesson row and the~2 MIN/FREEon a game row were all dropped. A row is its mark, its title, its eyebrow and its chevron.DICTIONARYas their eyebrow.FLIP AND RECALLandFROM THE DEFINITIONare 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, asFlashcardsCopy.practiceRowEyebrowandVocabCopy.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):SubGroupandPracticeGroupare now the design's oneDisclosurewith site-specific slots (headerPad: '12px 0',minHeight: 44, glyph 16, trailing gap 14, panelpaddingLeft: 34, paddingBottom: 4), so the sub-groups are built on that widget, not on their own chevron. The same drop dropped thePLACEHOLDERmeta and derives a game's tier fromFREE_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.
MODULE n · LABELwith 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 MINhaving gone with the 15 Sep drop. Open by default only when there is a single module.DICTIONARYas 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 toopacity: 0.55. Closed by default.240ms; gap 14, padding12px 0. Its children sit underpaddingLeft: 34,paddingBottom: 4.Rulings that beat the prototype
m.mod !== 'm1', which is the rule ADR-0007 forbids by name. Use the tier rule the catalog already uses.Acceptance criteria
DICTIONARYas their eyebrowdart format,flutter analyze, the metrics gate and the suite pass, with a changelog bullet, and the list is shown in a screenshotOut of scope
PLACEHOLDERrow 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.