G2G

Chapter Forty-Five

The Bridge

Die Brücke

Stone by stone, an arch rises across a dark chasm. The bridge assembles itself, each stone finding its place, the whole structure stronger than any single piece. Nine German words teach how ancient prefixes build new meanings. Be-, er-, ge- are the most elusive, the most transformative. They turn intransitive into transitive. They mark achievement. They gather plurality into wholeness. This is the secret architecture of German's power.

· · ·

A bridge is not built all at once. First comes a single stone, placed with intention. Then another, and another, each one finding its structural role, each one necessary to the whole. When the arch is complete, the bridge that emerges is stronger than any individual stone could be. It connects what was separate. It allows passage where there was only chasm. It transforms geography.

In German, three prefixes operate like stones in this bridge: be-, er-, and ge-. These are the bridge prefixes—the most subtle, the most difficult to understand, yet the most transformative. They do not simply modify meaning like other prefixes. They restructure the very nature of words. A verb that is intransitive—that cannot take a direct object—becomes transitive. An action that is attempted becomes accomplished. Multiple things that are scattered become gathered into unity.

These three prefixes are ancient beyond measure, reaching back into the deepest layers of Proto-Indo-European. They have been worn smooth by millennia of use, their original meanings obscured, their power concentrated into the most economical form. German has preserved them with remarkable fidelity. To master these prefixes is to understand something essential about how human language transforms raw experience into structured meaning.

This chapter teaches the most difficult and most essential lesson: that the smallest prefixes carry the greatest transformative power. Be-, er-, ge- are not decorations. They are the very architecture of meaning.

· · ·

Beginnen is "to begin," literally "to-in-to begin." The prefix be- means "around," "to," "towards," but when attached to verbs, it does something far more subtle: it marks the transition from intention to action. Bekommen is "to receive" or "to get." This is a word that requires careful attention because English speakers often mistake it for "to become" (which in German is werden). Bekommen means to acquire, to obtain, to have something come to you. The be- prefix marks that something moves toward you, is directed toward you.

Beschreiben is "to describe," literally "to-around-write." Without the be- prefix, schreiben is simply "to write." But with be-, the act of writing becomes the act of writing-around, of circling a subject with words, of delineating it from all sides. Description is not mere writing; it is writing that encompasses, that surrounds its object with precise language.

The prefix be- often has the effect of making verbs transitive—giving them the ability to take direct objects where they previously could not. Antwort is a noun meaning "answer." Beantworten means "to answer a question"—the verb that takes the question as its direct object. The be- prefix transforms a noun into a transitive verb, allowing action to flow toward an object.

beginnen /bəˈɡɪnən/
verb — to begin, to start, to commence; to undertake an action
PIE *gʰen- — "to give birth, to produce" + be- (around) — to begin giving forth
ENG begin — cognate; English preserves the root without the prefix
DEU be-ginnen — the be- prefix marks the act of starting as a directed, intentional action
ZHO 开始 (kāishǐ) / 着手 — "open-begin" / "grasp-hand" — both emphasize the initiation of action
The word beginnen is deceptively simple, but it reveals how prefixes work to mark transitions in meaning. The root ginnen (which barely survives in modern German except in this word) carries the sense of "giving forth." The prefix be- marks the beginning as a directed action: you do not simply start; you begin-toward, you direct your effort toward the commencement of something. This is why German maintains such a distinction between actions that are aimless and those that are directed: the prefixes mark intention.
bekommen /bəˈkɔmən/
verb — to receive, to get, to obtain; to acquire; to come to have; FALSE FRIEND: NOT "to become" (that is werden)
PIE *gʷem- + be- — "to come" + "to, toward" — to-have-come, to come-into-possession
ENG become (different root) — English false friend: NOT related to English "become"; closer to "come-to"
DEU be-kommen — "to-come"; marks something arriving at you, something obtained; CRITICAL: not the word for "to become"
ZHO 得到 (dédào) / 获得 — "get-arrive" / "acquire" — emphasizing something coming into your possession
Bekommen is famous for being a "false friend" for English learners. It does NOT mean "to become." It means "to receive" or "to get." The confusion arises because both German bekommen and English "become" are related to the root meaning "to come," but German preserved the original "to-get" sense while English evolved it into "to undergo change." In German, sein and werden are the verbs for "being" and "becoming"; bekommen is exclusively about obtaining, acquiring, and receiving. The be- prefix marks that something comes toward you, arrives at you, becomes yours.
beschreiben /bəˈʃʁaɪ̯bən/
verb — to describe, to depict, to set down in words; to characterize; to delineate all aspects
PIE *sker- + be- — "to write" + "around" — to write around, to circle with description, to encompass
ENG scribe (different formation) — English uses Latin roots for this sense; German uses native Germanic construction
DEU be-schreiben — "around-write"; makes schreiben transitive; description encompasses its object
ZHO 描述 (miáoshù) / 描写 — "sketch-express" / "sketch-depict" — both emphasize comprehensive rendering
Beschreiben demonstrates the power of the be- prefix to transform intransitive roots into transitive verbs. The root schreiben (to write) needs a be- prefix to take an object: you don't just "write"; you "write-around" something, encompassing it with language. The prefix suggests that description is an act of surrounding your subject with words, of delineating it from all angles. This is why beschreiben is more precise than simple writing: it implies completeness, comprehensiveness, the encirclement of meaning.

The key insight about be-: The be- prefix often marks causality, direction, or the acquisition of a quality. It frequently makes verbs transitive, allowing them to take direct objects. It suggests that an action is directed toward something, encompasses something, or results in something coming to you. Be- is the prefix of directed action and arrival.

· · ·

The prefix er- is perhaps the most elusive of all German prefixes. It does not have a simple English equivalent. In its most basic form, er- marks achievement, completion, or the reaching of a goal. Erklären is "to explain," literally "to-make-clear." The verb klären means "to clarify" or "to clear." With the er- prefix, it becomes erklären — "to make something clear enough to be understood." The prefix suggests that the action has been completed successfully, that understanding has been achieved.

Erinnern is "to remember," literally "to-bring-into-mind." The verb innerlich (inward, internal) contains the same root. With the er- prefix, the action of turning something inward, of bringing a past memory into present consciousness, is marked as achievement. You have successfully remembered. The memory has been brought forth.

Erzählen is "to tell" or "to narrate," literally "to-count-out." The root zählen means "to count." But with the er- prefix, counting becomes telling—the act of enumerating experiences, incidents, and details into a coherent narrative. The story emerges through the act of telling. The er- prefix marks the completion of this narrative act.

erklären /ɛɐˈklaːʁən/
verb — to explain, to make clear, to declare; to clarify; to profess understanding
PIE *kelǝ- + er- — "to drive, to clear" (klären) + "to achieve" (er-) — to successfully clear
ENG explain (Latin roots) — English uses Latin; German uses native Germanic construction
DEU er-klären — "achieve-clear"; marks explanation as successful clarification, not mere attempt
ZHO 解释 (jiěshì) / 说明 — "untie-release" / "speak-bright" — both emphasize the achieving of clarity
Erklären is among the most common German verbs, yet it contains profound linguistic architecture. The root klären (to clarify) combined with er- (achievement marker) creates the sense not of mere clarification, but of successful, complete explanation—the kind that achieves its goal of creating understanding. When a German speaker says "Ich erkläre," they are not tentatively offering an explanation; they are asserting that they will make something clear enough to be comprehended. The er- prefix marks the action as achievement-oriented.
erinnern /ɛɐˈɪnɐn/
verb — to remember, to recall, to bring to mind; to be a reminder of; reflexive: to remember oneself
PIE *h₁enǝ- (inner) + er- — "inner, internal" + "achieve" — to successfully bring inside the mind
ENG remember (Latin-influenced) — English uses Latin; German uses native word for internal movement
DEU er-innern — "achieve-internal"; marks memory as internal retrieval, moving the past inward
ZHO 记得 (jìde) / 想起 — "record-get" / "think-arise" — both emphasize memory's internal retrieval
Erinnern beautifully demonstrates how the er- prefix operates on internal actions. Memory is not external; it is the retrieval of what was external and bringing it into the inner world. The er- prefix marks this achievement of internalization. When you erinnern yourself of something, you are successfully drawing it inward, making it present in consciousness again. The reflexive form sich erinnern (to remember oneself) captures this: you turn yourself inward toward memory, achieving the presence of the past within your current consciousness.
erzählen /ɛɐˈtseːlən/
verb — to tell, to narrate, to recount; to relate a story; to speak of events in sequence
PIE *kel- (to count) + er- — "to count, enumerate" (zählen) + "achieve" — to achieve narrative through enumeration
ENG tell (different root) — English "tell" has different etymology; German preserves counting metaphor
DEU er-zählen — "achieve-count"; narrative is the achieved enumeration of events
ZHO 讲述 (jiǎngshù) / 叙述 — "speak-relate" / "order-speak" — both emphasize the structuring of events into narrative
Erzählen preserves a profound truth about narrative: that stories are built by counting, by enumerating events one after another until they form a pattern, a shape, a meaningful sequence. The er- prefix marks this achievement—the moment when individual events accumulate into a story, when enumeration becomes narration. This is why erzählen feels more active, more assertive than simply "saying": it is the achievement of making disparate moments cohere into meaningful narrative.

The key insight about er-: The er- prefix marks achievement, completion, or the successful reaching of a goal. It often appears in verbs that describe actions aimed at internal transformation or successful accomplishment. Er- is the prefix of achievement and fulfilled intention.

· · ·

The prefix ge- is perhaps the most ancient and the most difficult to pin down. In its essence, it marks collectivity, wholeness, the gathering of many into one. Geschenk is "gift," literally "something-sent-together." The roots suggest that a gift is something gathered up and sent as a whole to another person. Gespräch is "conversation," literally "the-speaking-together." Two or more people sprechen (speak); when they führen ein Gespräch (conduct a conversation), they are engaged in collective speaking, their words braided together into dialogue.

Gefühl is "feeling," literally "what is-felt-together." The individual sensations that arise in us are often so intertwined, so collectively present, that German language marks them with ge-, acknowledging that what we call "a feeling" is actually a gathering of multiple sensations into a unified emotional state.

The prefix ge- often marks not just plurality, but the cohesion of plural elements into a meaningful whole. This is why the prefix appears so frequently in nouns that describe complex phenomena: Gebirge (mountain range—multiple mountains gathered), Gesetz (law—words set together as binding rules), Geschwindigkeit (speed—the collective motion of all parts).

Geschenk /ɡəˈʃɛŋk/
noun — gift, present; something given; mark of generosity; token of affection
PIE *skenk- (to pour, to send) + ge- — "to send" + "together, collected" — something gathered and sent as a whole
ENG gift (different etymology) — English "gift" comes from different root; German preserves the sending metaphor
DEU ge-schenk — "together-sent"; implies gift as a collected, intentional offering
ZHO 礼物 (lǐwù) / 赠送 — "ritual-thing" / "gift-send" — both emphasize intentional offering
Geschenk reveals how the ge- prefix can mark intention and gathering. A gift is not random; it is something carefully gathered together (multiple objects, wrapped and bundled, or multiple qualities bundled into a single gesture) and sent to another with intention. The ge- prefix encodes that a gift is a unified whole, a collected offering, not disparate items but an intentional whole presented as such. This is why a true gift requires presentation, ceremony, acknowledgment—because it is marked by the ge- prefix as something gathered into meaning.
Gespräch /ɡəˈʃpʁɛɪ̯x/
noun — conversation, dialogue, discussion; the act of speaking together; exchange of words
PIE *sprek- (to speak) + ge- — "to speak" + "together, collective" — the collective act of speaking together
ENG conversation (Latin-based) — English uses Latin; German preserves the speaking-together metaphor
DEU ge-sprach (archaic) → Gespräch — "together-spoke"; marked as collective speaking, not soliloquy
ZHO 对话 (duìhuà) / 谈话 — "paired-speak" / "discuss-speak" — both emphasize mutual, collective speaking
Gespräch is one of the clearest examples of the ge- prefix's power to mark collectivity. Individual speech is Rede or Kundgabe (utterance, pronouncement). But when two or more people engage in mutual speaking, exchange words, respond to each other, the German language marks this fundamentally different activity with the ge- prefix: Gespräch. It is not merely multiple instances of speaking occurring in proximity; it is the unified phenomenon of speaking-together, words braided into dialogue, language becoming relational and reciprocal.
Gefühl /ɡəˈfyːl/
noun — feeling, emotion, sensation; sense; intuition; the affective state arising from multiple stimuli
PIE *pʰel- (to feel, to touch) + ge- — "to feel" + "together, gathered" — multiple sensations gathered into unified emotion
ENG feeling (different prefix structure) — English forms differently; German preserves the gathering metaphor
DEU ge-fühl — "together-felt"; marks emotion as collective sensation, not individual isolated impulse
ZHO 感觉 (gǎnjué) / 情感 — "sense-perceive" / "emotion-sensation" — both emphasize multiple sensations combining
Gefühl reveals the profundity of the ge- prefix when applied to internal phenomena. A single sensation might be called Empfindung (a sensation, a physical feeling). But when multiple sensations cohere—when the rapid heartbeat, the heat rising in your face, the trembling in your limbs, the thought in your mind, the memory in your consciousness all come together in one unified state—German marks this gathering with ge-: Gefühl. It is not a single sensation but the whole-ness of an emotional state, multiple elements gathered into meaningful unity.

The key insight about ge-: The ge- prefix marks collectivity, wholeness, and the gathering of multiple elements into unified phenomena. It transforms plural into singularity—many things become one thing. Ge- is the prefix of unity, collection, and the meaningful whole.

· · ·

All nine words in this chapter demonstrate the three great bridge prefixes of German. Together, they show how the smallest linguistic elements carry the greatest transformative power.

Be-: Begins, receives, describes. Marks direction, acquisition, directed action. Makes verbs transitive. Suggests things are directed toward you or encompassed by action.

Er-: Clarifies, remembers, narrates. Marks achievement, completion, successful accomplishment. Suggests that an action has reached its goal or achieved internal transformation.

Ge-: Gathers, unifies, collects. Marks collectivity, wholeness, multiple elements becoming one. Transforms plural into singular meaning. Suggests multiple elements cohering into meaningful unity.

The bridge prefixes are the ancient architecture of German meaning. Be-, er-, ge- do not simply modify words. They restructure them, directing meaning, marking achievement, gathering plurality into wholeness. This is how language builds complexity from simplicity. This is how stone by stone, a bridge assembles itself.

· · ·

Now that you understand be-, er-, and ge-, try these guesses. Use the bridge metaphor as your foundation.

· · ·

Advanced guesses: test your understanding of how these prefixes combine.

· · ·

Check Your Understanding

Test your mastery of Chapter 45's bridge prefixes. Aim for 80%.

Words from Die Brücke (The Bridge)

beginnen
to begin
bekommen
to receive, get
beschreiben
to describe
erklären
to explain
erinnern
to remember
erzählen
to tell, narrate
Geschenk
gift
Gespräch
conversation
Gefühl
feeling, emotion
Patterns Discovered
Be- Makes Verbs Transitive — The prefix be- transforms intransitive verbs into transitive ones. Schreiben (to write) becomes beschreiben (to write around, to describe). Antwort (answer, noun) becomes beantworten (to answer, verb). Direction and encompassment flow through this prefix.

Er- Marks Achievement — The prefix er- does not merely suggest action; it marks successful completion. Klären (to clarify, tentative) becomes erklären (to explain successfully). Zählen (to count) becomes erzählen (to achieve narrative through enumeration). Achievement is embedded in the word itself.

Ge- Gathers Multiplicity into Unity — The prefix ge- transforms plural into singular, many into one. Sprechen (to speak, individual) becomes Gespräch (conversation, collective). Fühlen (to feel, singular) becomes Gefühl (feeling, the unity of many sensations). Wholeness emerges through gathering.

Ancient Prefixes, Silent Power — Be-, er-, ge- are among the oldest prefixes in German, yet they operate almost invisibly in everyday speech. Their power lies in their subtlety: they restructure meaning itself without drawing attention to themselves, like stones in an arch that are stronger together than separately.

Bauwerkstatt

Building Workshop — Three Levels of Production Exercises
1 Wortbaukasten — Word Building Kit
Build the German phrase by clicking words in order:
Available words:
Build: "We observe the birds"
Available words:
Build: "The athletes achieve their goals"
Available words:
Build: "A thought is valuable"
Available words:
2 Lückensatz — Gap Sentence
Fill in the blank: "Wir _______ die Vögel _______." (We ___ the birds.)
Fill in the blank: "Die Athleten _______ ihre Ziele." (The athletes ___ their goals.)
Fill in the blank: "Ein _______ ist wertvoll." (A ___ is valuable.)
Fill in the blank: "Das _______ ist tief." (The ___ is deep.)
3 Freies Bauen — Free Building
Translate to German: "to observe"
Translate to German: "to achieve"
Translate to German: "thought"
Translate to German: "feeling"
Your Progress: 0 / 12 Correct

Lesen & Hören — Read and Listen

Wir beobachten die Natur sorgfältig.
Die Wissenschaftler erreichen ihre Ziele.
Ein Gedanke führt zu neuen Erkenntnissen.
Das Gefühl ist tief und wertvoll.

Verständnisfragen — Comprehension Questions

1. What prefix patterns were used in the passage?
The prefixes from this chapter
Random prefixes
No prefixes at all
2. Identify a verb with a chapter prefix:
Any verb from the passage using this chapter's prefixes
A verb without prefixes
A noun instead of a verb
3. Fill in the blank with a conjugated verb from this chapter:
4. Understand the spatial or temporal relationships expressed:
The prefixes encode different meanings related to time or space
The prefixes have no meaning
The prefixes are decorative

Diktat — Dictation Exercise

Listen to a sentence and type what you hear. Click the button to hear each sentence once.

Sentence 1 of 2
A G2G Advisory Project
Your Progress
Words Collected 427 / 850 (50%)
Click to see all words ▾
Patterns & Grammar 99 / 145 (68%)
Click to see all patterns ▾
/* === BAUWERKSTATT SYSTEM === */ // Levenshtein distance function for fuzzy matching function levenshteinDistance(a, b) { const aL = a.toLowerCase(), bL = b.toLowerCase(); const track = Array(bL.length + 1).fill(null).map(() => Array(aL.length + 1).fill(0)); for (let i = 0; i <= aL.length; i++) track[0][i] = i; for (let j = 0; j <= bL.length; j++) track[j][0] = j; for (let j = 1; j <= bL.length; j++) { for (let i = 1; i <= aL.length; i++) { const indicator = aL[i - 1] === bL[j - 1] ? 0 : 1; track[j][i] = Math.min( track[j][i - 1] + 1, track[j - 1][i] + 1, track[j - 1][i - 1] + indicator ); } } return track[bL.length][aL.length]; } // Bauwerkstatt exercise data (to be filled with chapter-specific data) const bauwerkstattData = { level1: [], level2: [], level3: [] }; // State tracking let bauwerkstattState = { level1: { completed: [false, false, false, false], score: 0 }, level2: { completed: [false, false, false, false], score: 0 }, level3: { completed: [false, false, false, false], score: 0 }, assembled: [[], [], [], []] }; // Initialize Bauwerkstatt function initBauwerkstatt() { if (bauwerkstattData.level1.length === 0) return; // Level 1: Word Assembly bauwerkstattData.level1.forEach((ex) => { const bankId = `word-bank-${ex.id}`; const bank = document.getElementById(bankId); if (bank) { bank.innerHTML = ''; ex.words.forEach(word => { const chip = document.createElement('div'); chip.className = 'word-chip'; chip.textContent = word; chip.onclick = () => addToAssembly(ex.id, word); bank.appendChild(chip); }); } bauwerkstattState.assembled[ex.id - 1] = []; }); updateProgress(); } function addToAssembly(exId, word) { const areaId = `assembly-area-${exId}`; const area = document.getElementById(areaId); const bankId = `word-bank-${exId}`; const bank = document.getElementById(bankId); if (!bauwerkstattState.assembled[exId - 1]) { bauwerkstattState.assembled[exId - 1] = []; } // Add to assembly area const chip = document.createElement('div'); chip.className = 'word-chip placed'; chip.textContent = word; chip.onclick = () => removeFromAssembly(exId, word, chip); area.appendChild(chip); bauwerkstattState.assembled[exId - 1].push(word); // Mark as unavailable in bank const bankChips = bank.querySelectorAll('.word-chip'); bankChips.forEach(c => { if (c.textContent === word) c.classList.add('unavailable'); }); } function removeFromAssembly(exId, word, chipEl) { const bankId = `word-bank-${exId}`; const bank = document.getElementById(bankId); chipEl.remove(); const idx = bauwerkstattState.assembled[exId - 1].indexOf(word); if (idx > -1) bauwerkstattState.assembled[exId - 1].splice(idx, 1); // Re-enable in bank const bankChips = bank.querySelectorAll('.word-chip'); bankChips.forEach(c => { if (c.textContent === word) c.classList.remove('unavailable'); }); } function undoWordAssembly(exId) { const areaId = `assembly-area-${exId}`; const area = document.getElementById(areaId); const bankId = `word-bank-${exId}`; const bank = document.getElementById(bankId); area.innerHTML = ''; bauwerkstattState.assembled[exId - 1] = []; // Reset all chips in bank const bankChips = bank.querySelectorAll('.word-chip'); bankChips.forEach(c => c.classList.remove('unavailable')); const feedbackId = `feedback-${exId}`; const fb = document.getElementById(feedbackId); if (fb) fb.classList.remove('show', 'correct', 'close', 'incorrect'); } function checkWordAssembly(exId) { const ex = bauwerkstattData.level1[exId - 1]; if (!ex) return; const assembled = bauwerkstattState.assembled[exId - 1].join(' ').toLowerCase(); const correct = ex.correct.join(' ').toLowerCase(); const feedbackId = `feedback-${exId}`; const fb = document.getElementById(feedbackId); if (!fb) return; if (assembled === correct) { fb.className = 'exercise-feedback show correct'; fb.innerHTML = `
✓ Correct!
${ex.explanation}
`; if (!bauwerkstattState.level1.completed[exId - 1]) { bauwerkstattState.level1.completed[exId - 1] = true; bauwerkstattState.level1.score++; updateProgress(); } } else { fb.className = 'exercise-feedback show incorrect'; fb.innerHTML = `
Not quite yet.
Try again. The correct phrase is: ${ex.answer}
`; } } // Level 2 & 3: Gap sentences and free building function handleGapKeypress(event, exId) { if (event.key === 'Enter') checkGapSentence(exId); } function handleFreeKeypress(event, exId) { if (event.key === 'Enter') checkFreeBuilding(exId); } function checkGapSentence(exId) { const ex = bauwerkstattData.level2[exId - 1]; if (!ex) return; const input = document.getElementById(`gap-input-${exId}`); const answer = input.value.trim(); const feedbackId = `gap-feedback-${exId}`; const fb = document.getElementById(feedbackId); const accepted = ex.accepted_answers; const isCorrect = accepted.some(a => a.toLowerCase() === answer.toLowerCase()); if (isCorrect) { fb.className = 'exercise-feedback show correct'; fb.innerHTML = `
✓ Correct!
${answer.charAt(0).toUpperCase() + answer.slice(1)}. ${ex.explanation}
`; if (!bauwerkstattState.level2.completed[exId - 1]) { bauwerkstattState.level2.completed[exId - 1] = true; bauwerkstattState.level2.score++; updateProgress(); } } else { // Check for close matches let closest = null; let minDist = Infinity; for (const a of accepted) { const dist = levenshteinDistance(answer, a); if (dist < minDist) { minDist = dist; closest = a; } } if (minDist <= 2) { // Check if there's a specific error message let specificFeedback = null; if (ex.close_errors) { for (const err of ex.close_errors) { if (err.wrong.toLowerCase() === answer.toLowerCase()) { specificFeedback = err.feedback; break; } } } fb.className = 'exercise-feedback show close'; fb.innerHTML = `
Almost!
${specificFeedback || `You wrote '${answer}' — the right form is '${closest}'. ${ex.explanation}`}
`; } else { fb.className = 'exercise-feedback show incorrect'; fb.innerHTML = `
Not quite.
The answer is ${closest}. ${ex.explanation}
`; } } } function checkFreeBuilding(exId) { const ex = bauwerkstattData.level3[exId - 1]; if (!ex) return; const input = document.getElementById(`free-input-${exId}`); const answer = input.value.trim(); const feedbackId = `free-feedback-${exId}`; const fb = document.getElementById(feedbackId); const accepted = ex.accepted_answers; const isCorrect = accepted.some(a => a.toLowerCase() === answer.toLowerCase()); if (isCorrect) { fb.className = 'exercise-feedback show correct'; fb.innerHTML = `
✓ Correct!
${ex.explanation}
`; if (!bauwerkstattState.level3.completed[exId - 1]) { bauwerkstattState.level3.completed[exId - 1] = true; bauwerkstattState.level3.score++; updateProgress(); } } else { // Check for close matches let closest = null; let minDist = Infinity; for (const a of accepted) { const dist = levenshteinDistance(answer, a); if (dist < minDist) { minDist = dist; closest = a; } } if (minDist <= 2) { // Check for specific error feedback let specificFeedback = null; if (ex.close_errors) { for (const err of ex.close_errors) { if (err.wrong.toLowerCase() === answer.toLowerCase()) { specificFeedback = err.feedback; break; } } } fb.className = 'exercise-feedback show close'; fb.innerHTML = `
Almost!
${specificFeedback || `You wrote '${answer}' — the right answer is '${closest}'. ${ex.explanation}`}
`; } else { fb.className = 'exercise-feedback show incorrect'; fb.innerHTML = `
Not quite.
The answer is ${closest}. ${ex.explanation}
`; } } } function updateProgress() { const total = 12; // 4 + 4 + 4 const score = bauwerkstattState.level1.score + bauwerkstattState.level2.score + bauwerkstattState.level3.score; const scoreEl = document.getElementById('bauwerkstatt-score'); if (scoreEl) scoreEl.textContent = score; const bar = document.getElementById('bauwerkstatt-progress-bar'); if (bar) { bar.innerHTML = ''; const allCompleted = [ ...bauwerkstattState.level1.completed, ...bauwerkstattState.level2.completed, ...bauwerkstattState.level3.completed ]; allCompleted.forEach(completed => { const dot = document.createElement('div'); dot.className = 'progress-dot' + (completed ? ' completed' : ''); bar.appendChild(dot); }); } } // Initialize on page load document.addEventListener('DOMContentLoaded', () => { initBauwerkstatt(); }); /* === LESEN & HÖREN SECTION === */ const dictationSentences = []; let currentSpeed = 0.95; let isListening = false; let currentDictationIndex = 0; let isSpeaking = false; /** * Word-level diff for showing what changed */ function wordDiff(actual, expected) { const actualWords = actual.toLowerCase().split(/\s+/); const expectedWords = expected.toLowerCase().split(/\s+/); const result = []; const maxLen = Math.max(actualWords.length, expectedWords.length); for (let i = 0; i < maxLen; i++) { const aWord = actualWords[i] || ''; const eWord = expectedWords[i] || ''; if (aWord === eWord) { result.push(`${eWord}`); } else { result.push(`${aWord}`); } } return result.join(' '); } /** * Start listening to the passage */ function startListening() { if (isSpeaking) return; isListening = true; document.getElementById('listen-btn').style.display = 'none'; document.getElementById('stop-btn').style.display = 'inline-block'; const sentences = document.querySelectorAll('.passage-sentence'); sentences.forEach(s => s.classList.remove('reading')); // Speak with pauses between sentences const utterances = []; sentences.forEach((sentenceEl, idx) => { const text = sentenceEl.textContent.trim(); const utterance = new SpeechSynthesisUtterance(text); utterance.lang = 'de-DE'; utterance.rate = currentSpeed; utterance.onstart = () => { sentenceEl.classList.add('reading'); }; utterance.onend = () => { sentenceEl.classList.remove('reading'); // Add a pause between sentences if (idx < sentences.length - 1) { setTimeout(() => { if (isListening && idx + 1 < utterances.length) { speechSynthesis.speak(utterances[idx + 1]); } }, 300); } }; utterances.push(utterance); }); isSpeaking = true; if (utterances.length > 0) { speechSynthesis.speak(utterances[0]); } } /** * Stop listening */ function stopListening() { isListening = false; isSpeaking = false; speechSynthesis.cancel(); document.getElementById('listen-btn').style.display = 'inline-block'; document.getElementById('stop-btn').style.display = 'none'; document.querySelectorAll('.passage-sentence').forEach(s => s.classList.remove('reading')); } /** * Set speech rate */ function setSpeed(rate) { currentSpeed = rate; document.querySelectorAll('.speed-btn').forEach(btn => btn.classList.remove('active')); if (rate === 0.7) { document.getElementById('speed-slow').classList.add('active'); } else { document.getElementById('speed-normal').classList.add('active'); } // If currently speaking, restart with new rate if (isListening) { stopListening(); setTimeout(() => startListening(), 300); } } /** * Check comprehension question */ function checkComprehension(qNum, element, isCorrect) { // Disable all options for this question const options = element.parentElement.querySelectorAll('.comp-option'); options.forEach(opt => { opt.style.pointerEvents = 'none'; opt.style.opacity = '0.7'; }); const feedback = document.getElementById(`comp-feedback-${qNum}`); if (isCorrect) { element.classList.add('correct'); feedback.textContent = '✓ Correct!'; feedback.classList.add('show', 'correct'); } else { element.classList.add('incorrect'); feedback.textContent = '✗ Incorrect.'; feedback.classList.add('show', 'incorrect'); } } /** * Check fill-in-the-blank answer */ function checkFillBlank() { const input = document.getElementById('fill-blank-input'); const answer = 'kommt'; const userAnswer = input.value.trim().toLowerCase(); const feedback = document.getElementById('comp-feedback-3'); const distance = levenshteinDistance(userAnswer, answer); if (distance === 0) { feedback.textContent = '✓ Perfect!'; feedback.classList.add('show', 'correct'); input.style.borderColor = 'rgba(74, 180, 100, 0.5)'; } else if (distance <= 2) { feedback.textContent = `✓ Very close! The answer is: ${answer}`; feedback.classList.add('show', 'correct'); input.style.borderColor = 'rgba(74, 180, 100, 0.5)'; } else { feedback.textContent = `The correct answer is: ${answer}`; feedback.classList.add('show', 'incorrect'); input.style.borderColor = 'rgba(232, 164, 74, 0.5)'; } input.disabled = true; } /** * Play dictation sentence */ function playDictation() { if (currentDictationIndex >= dictationSentences.length) { return; } const sentence = dictationSentences[currentDictationIndex]; const utterance = new SpeechSynthesisUtterance(sentence); utterance.lang = 'de-DE'; utterance.rate = 0.8; document.getElementById('dictation-play-btn').disabled = true; utterance.onend = () => { document.getElementById('dictation-play-btn').disabled = false; }; speechSynthesis.speak(utterance); } /** * Check dictation answer */ function checkDictation() { const input = document.getElementById('dictation-input'); const userAnswer = input.value.trim(); const expectedAnswer = dictationSentences[currentDictationIndex]; const feedback = document.getElementById('dictation-feedback'); const result = document.getElementById('dictation-result'); if (!userAnswer) { feedback.textContent = 'Please type something first.'; feedback.classList.add('show', 'incorrect'); return; } const distance = levenshteinDistance(userAnswer, expectedAnswer); const maxDistance = Math.ceil(expectedAnswer.length * 0.15); feedback.classList.remove('correct', 'incorrect'); result.classList.remove('show'); if (distance === 0) { feedback.textContent = '✓ Perfect! You got it exactly right.'; feedback.classList.add('show', 'correct'); result.classList.add('show'); result.innerHTML = `Correct sentence: ${expectedAnswer}`; } else if (distance <= 3) { feedback.textContent = `✓ Very close! Only a few words different.`; feedback.classList.add('show', 'correct'); result.classList.add('show'); result.innerHTML = `What you wrote: ${wordDiff(userAnswer, expectedAnswer)}
Expected: ${expectedAnswer}`; } else { feedback.textContent = '✗ Not quite. Try again or listen once more.'; feedback.classList.add('show', 'incorrect'); result.classList.add('show'); result.innerHTML = `Expected: ${expectedAnswer}`; } // Update counter and prepare for next if (currentDictationIndex < dictationSentences.length - 1) { // Show "Next Sentence" button instead of auto-advancing let nextBtn = document.getElementById('dictation-next-btn'); if (!nextBtn) { nextBtn = document.createElement('button'); nextBtn.id = 'dictation-next-btn'; nextBtn.textContent = 'Next Sentence →'; nextBtn.style.cssText = 'margin-top:16px;padding:10px 24px;background:rgba(232,164,74,0.15);color:#e8a44a;border:1px solid rgba(232,164,74,0.3);border-radius:8px;cursor:pointer;font-family:inherit;font-size:0.95rem;display:block;'; nextBtn.onmouseover = function() { this.style.background = 'rgba(232,164,74,0.25)'; }; nextBtn.onmouseout = function() { this.style.background = 'rgba(232,164,74,0.15)'; }; feedback.parentNode.insertBefore(nextBtn, feedback.nextSibling); } nextBtn.style.display = 'block'; nextBtn.onclick = function() { currentDictationIndex++; updateDictationCounter(); input.value = ''; feedback.classList.remove('show'); result.classList.remove('show'); this.style.display = 'none'; }; } else { document.getElementById('dictation-play-btn').textContent = '✓ Dictation Complete!'; document.getElementById('dictation-play-btn').disabled = true; } } /** * Update dictation counter */ function updateDictationCounter() { const counter = document.getElementById('dictation-counter'); counter.textContent = `Sentence ${currentDictationIndex + 1} of ${dictationSentences.length}`; } // Initialize dictation counter on page load document.addEventListener('DOMContentLoaded', () => { updateDictationCounter(); });