Anglicize tippen's codebase and finish pending UI/curriculum cleanup

- Rename all German identifiers, types, mode ids, file names, CSS classes
  and data-attributes to English throughout tippen/src; only user-facing
  text (lesson titles, word lists, labels, spoken praise) stays German.
- Add a word/nonsense-word list to the "Übung: die Grundstellung" home-row
  lesson in the curriculum.
- Remove the unused HandHint component and speech.ts, and carry forward
  the in-progress App.tsx/component/generator/progress edits from other
  sessions.
- Refresh the regenerated music-library cache index.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-12 00:07:18 +02:00
parent f97de193d8
commit 498243af46
38 changed files with 1425 additions and 1599 deletions

View File

@@ -86,7 +86,7 @@ export function press(state: RunState, key: string, now: number): [RunState, Run
if (expected === undefined) return [state, []];
// The layout is what decides case, not the run: typing "A" where "a" is wanted is
// correct. Capitals are their own lesson (Welt 4), and that lesson's target text
// correct. Capitals are their own lesson (world 4), and that lesson's target text
// carries the capital, so this comparison still teaches Shift where it matters.
const correct = key.toLowerCase() === expected.toLowerCase();
const startedAt = state.startedAt ?? now;
@@ -117,7 +117,7 @@ export function press(state: RunState, key: string, now: number): [RunState, Run
}
/** Give up on the rest of the line - what Escape does. The run is still graded on what
* was typed, so a half-finished Blasenplatzen round still earns its Perlen. */
* was typed, so a half-finished bubbles round still earns its pearls. */
export function abandonRun(state: RunState, now: number): RunState {
if (isFinished(state) || state.startedAt === null) return state;
return { ...state, finishedAt: now };