fix(#609): embedding level — tap-to-group (mobile-playable)#610
Merged
Conversation
…p (mobile) The Embeddings level used free-form drag of a word from a bottom tray into a tall 2D plane — unplayable on a phone (invisible cluster zones, tray far below the drop area, 2D drag doesn't work with touch+scroll). Replaced the mechanic with a tap-the-meaning-group picker: one card per word + Animals/Fruits/Vehicles buttons, mirroring the mobile-proven levelCutoff pattern and reusing its .cut-* styling. Same lesson (similar meanings group together), no dragging; score = correct group per word. Removed the now-dead .emb-*/cluster-* CSS (incl. the @media rules). JS node --check clean; LEVELS still 11. Closes #609 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
atlas-apex
commented
Jun 9, 2026
atlas-apex
left a comment
Collaborator
Author
There was a problem hiding this comment.
Code Review: PR #610
Commit: 2ecbe380ce9591876d721dbc24e3bf6b19b7dd8d
Posted as a comment (cannot self-approve own PR). Verdict is APPROVED — Rex approval marker written.
Summary
Rewrites the Embeddings level (level2) in site/game.html from a free-form drag-into-2D-plane mechanic (unplayable on touch+scroll phones) to a tap-to-group picker cloned from the existing mobile-proven levelCutoff pattern, reusing its .cut-* styling. Removes the now-dead .emb-* / .cluster-* CSS and its two @media rules. Net +64/−202.
Checklist Results
- ✅ Architecture & Design: Pass — reuses an existing, proven in-file pattern; no new abstraction
- ✅ Code Quality: Pass
- ✅ Testing: Pass — static site;
node --checkis the gate (clean) - ✅ Security: Pass — no auth/secrets/input-trust surface
- ✅ Performance: Pass
- ✅ PR Description & Glossary: Pass — Summary + Testing + Glossary all present, narrative bullets
- ⚠ Summary Bullet Narrative: Pass — bullets carry what + why
- ✅ Technical Decisions (AgDR): N/A — clones an existing level pattern, no new decision
- ✅ Adopter Handbooks: N/A — no handbook triggers on a static HTML/inline-JS diff (migration-safety is blocking but matches no migration paths here)
Verification performed
- Syntax: extracted the single inline
<script>and rannode --check→ clean. - Registry intact:
LEVELSstill has 11 entries;level2still registered with its slide;foottext updated to the tap wording (Tap the meaning group each word belongs to.). - Completable + correct scoring: 9 word-cards (dog/cat/wolf, apple/banana/grape, car/truck/bicycle, shuffled), 3 pick buttons each. Submit is
disableduntilObject.keys(choice).length === WORDS.length.choiceis keyed by theWORDS.forEachindexi, and submit iterateslist.childrenwith the same index (children appended in the same order) — no off-by-one.got = choice[i]is guaranteed defined at submit time by the gate, sopickBtns[got]cannot be undefined — no crash. Score =Math.round(correct/9*100), writesstate.levelScores[state.level](same shape as every other level), callsaddScore+showResult. - Class reuse is real:
.cut-list/.cut-card/.cut-q/.cut-btns/.cut-pick(.sel/.right/.wrong/.truth)/.cut-verdictall still defined (lines 561–580) and live —levelCutoff(line 2269) uses the same set. The right+truth class composition on a correct pick is harmless (border/bg vs inset shadow). - Dead CSS genuinely gone: only remaining
.emb-*/.cluster-*textual match is the removal comment; the new code's "cluster" prose is incidental. Thedragifyhelper is NOT orphaned — still used by the prompt-builder level (line 1434). - Flow intact:
hintBtn/footnote/skipBtnare global; skip is wired once toskipLevel()and re-shown per render, level2 sets the updated hint copy. Skip still works. - Scope clean: 5 diff hunks, all level2 + its dead CSS — no collateral edits to other levels.
- Bookkeeping: PR body has Summary + Testing + Glossary;
Closes #609(verified OPEN); HEAD SHA matches.
Issues Found
None.
Suggestions
None blocking. Sound fix-forward.
Verdict
APPROVED
🤖 Reviewed by Rex (Code Reviewer Agent)
📌 Reviewed commit: 2ecbe380ce9591876d721dbc24e3bf6b19b7dd8d
This was referenced Jun 9, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
.cut-cardper word with three tappable buttons (🐾 Animals / 🍎 Fruits / 🚗 Vehicles), mirroring the mobile-provenlevelCutoffpattern and reusing its.cut-*styling (so it inherits the existing mobile breakpoints — zero new CSS). Tap a group → submit (gated until all 9 picked) → reveal right/wrong per word + the correct group →showResult. Score = correct groups ÷ 9 × 100..emb-*/.cluster-*CSS (including the two@mediarules that propped up the old plane) — net −138 lines.Testing
node --checkon the inline script — clean;LEVELSstill 11.level2+ its dead CSS touched).Closes #609
Glossary
.cut-*