G2G

Chapter Forty-Two

The Beginning

Der Anfang

Three paths converge. Three particles flow together. Three spatial prefixes unlock the doors to hundreds of verbs. Where does an action begin? Where does it happen? Where do we stand in relation to others? These ancient prepositions became the prefixes that shape German's most common verbs.

· · ·

Imagine three rivers flowing from three different mountains. One flows from the north, carrying gold in its current. One flows from the east, carrying silver. One flows from the south, carrying copper. For hundreds of miles they flow separately, carving their own valleys, sustaining their own villages, singing their own songs. But then the valleys converge. The three rivers meet.

At the place where they meet, something remarkable happens. The three currents do not erase each other. Instead, they mingle. The gold and silver and copper swirl together in a single stream, creating colors that existed in neither river alone. And from that single stream flows something stronger, something more powerful, something that carries all three currents forward.

This is the image of an-, bei-, and mit-. Three spatial prefixes that flow from three different origins in Proto-Germanic. Three directions encoded into the very structure of how German speakers understood the world. Where is it? At (an). Where does it relate to me? By/near (bei). In what relation do we stand? With (mit). These simple spatial concepts became the basis for hundreds of verbs, for ways of thinking about action, participation, and connection that are so deeply embedded in German that native speakers barely notice them at all.

This chapter is about convergence. It is about how spatial thinking becomes abstract thinking, and how the oldest prepositions in a language become the most productive prefixes.

· · ·

The prefix an- begins in space. It means "at," "on," "toward." When you say something is "an der Wand" (on the wall), you are using the preposition an to place something in a spatial location. But watch what happens when this spatial word becomes a prefix.

Anfangen is "to begin," or more literally, "to grab at." From fangen (to catch, to seize), with an- (at, toward): you grab at something, you seize the beginning of an action. The spatial becomes temporal. The physical act of grasping becomes the abstract concept of starting.

Ankommen is "to arrive," or more precisely, "to come-at." From kommen (to come), with an- (at, toward): you come toward a destination. You are moving through space toward a specific point. This is not vague arrival, but arrival with direction and intention, arrival at a place.

Anrufen is "to call" or "to telephone," literally "to call-at." From rufen (to call, to shout), with an- (at, toward): your voice is directed toward a specific person. You are not calling into the void. You are calling at someone, calling in their direction, calling to establish contact.

an- /an/
prefix — spatial location "at," "on," "toward"; temporal meaning "at the beginning"; directional meaning "to, toward, at"
PIE *h₂enH- — root meaning "to be at a location"
ENG on — related, though English lost the separate prefix use
DEU an- — inseparable prefix; originally a preposition meaning "at, on, toward"
ZHO 在 / 向 — zài / xiàng — "at location" and "toward direction" — similar spatial concepts
The prefix an- preserves one of the oldest spatial concepts in Indo-European: the idea of being AT a location or moving TOWARD it. It appears in many Germanic languages and is related to English "on." When an- became a prefix attached to verbs, it retained this spatial meaning but transformed it: temporal beginning (anfangen), spatial arrival (ankommen), directional communication (anrufen). The spatial → abstract transformation shows how languages build complex meanings from simple physical experiences. A German speaker saying "Ich fange an zu arbeiten" (I begin to work) is literally saying "I grab-at to work," preserving that ancient image of seizing the beginning of an action.

The key insight: an- is always about DIRECTION, about TARGETING, about POINTING AT. Whether you are arriving (ankommen), calling (anrufen), looking (anschauen), or beginning (anfangen), the prefix carries this sense of directionality. Something is aimed at, moved toward, or seized at its starting point.

· · ·

The prefix bei- is often harder for English speakers to understand because English has largely lost it as a productive prefix. But in German, it means "by," "near," "with," "together with." It is about proximity and association. When you are at someone's house, you are bei them — not "at" them, but "by" them, "near" them, "in their presence."

Beibringen is "to teach," literally "to bring-by" or "to bring-near." From bringen (to bring), with bei- (by, near, with): when you teach someone something, you bring knowledge near to them, you place it in proximity to their mind. Teaching is not imposing knowledge from above; it is bringing it alongside someone, making it available to them.

Beitragen is "to contribute," literally "to carry-by" or "to bring-alongside." From tragen (to carry, to bear), with bei- (by, alongside): when you contribute to a project, you carry something alongside the others' work. You are not leading; you are walking alongside, adding your effort to the collective effort.

Beispiel is "example," but the word itself is a fossil of this old bei- prefix. The spiel part (from "Spiel," game or play) gets a bei- prefix, creating the word for "something played alongside," "something shown nearby," "an example played out next to the concept."

bei- /baɪ̯/
prefix — proximity "by," "near," "alongside"; association "together with"; assistance "to help"
PIE *h₂enti- — root meaning "opposite, before, in front of"
ENG by — cognate; English preserved this as a preposition but lost it as a productive prefix
DEU bei- — separable prefix in some contexts; literally "by, near, with"
ZHO 跟 / 和 — gēn / hé — "together with," "alongside" — association and proximity
The prefix bei- encodes a different spatial relationship than an-. Where an- is about targeting and direction, bei- is about being present alongside. It is about proximity, not pursuit. The word Beispiel (example) reveals the ancient thinking: an example is something "played alongside" the main concept, something that illuminates by analogy. In compounds like beibringen (to teach), the prefix carries the sense of making something available nearby, placing knowledge within reach. This is fundamentally different from the directed motion of an-. The bei- prefix suggests cooperation, assistance, and presence rather than targeting and direction.

The key insight: bei- is about ASSOCIATION, about BEING ALONGSIDE, about MAKING AVAILABLE. Whether you are teaching (beibringen), contributing (beitragen), or providing an example (Beispiel), the prefix carries this sense of proximity and cooperation.

· · ·

The prefix mit- means "with," "together," "co-." It is the most explicitly relational of the three prefixes. Where an- points toward a target and bei- suggests proximity, mit- explicitly indicates togetherness, shared action, mutual participation.

Mitmachen is "to participate," literally "to make-with." From machen (to make, to do), with mit- (with, together): when you participate in something, you make alongside others. You are not making independently; you are making together with them, your actions intertwined with theirs.

Mitnehmen is "to take along," literally "to take-with." From nehmen (to take), with mit- (with, together): you take something or someone with you. The prefix transforms a solitary action (taking) into a shared action (taking-along, including).

Mitglied is "member," literally "with-limb." From Glied (limb, member), with mit- (with, together): a member is a limb that functions with the body. You are not an independent limb; you are a limb connected to and functioning as part of a larger organism. The metaphor is ancient but profound.

Mitleid is "compassion" or "sympathy," literally "with-suffering." From Leid (suffering, sorrow), with mit- (with, together): compassion is not pity from above. It is suffering-with, the act of standing alongside someone in their pain, of sharing their emotional burden. The prefix makes the meaning precise: you feel their feeling, you suffer their suffering, you are present with them in their distress.

mit- /mɪt/
prefix — togetherness "with," "together"; co-action "co-"; shared experience "together with"
PIE *meti- — root meaning "with," "in the middle"
ENG mid — cognate; preserved in "amidst" but no longer productive as a standalone prefix
DEU mit- — separable prefix; meaning "with, together, co-"
ZHO 一起 / 同 — yīqǐ / tóng — "together," "same" — expressing togetherness and sameness
The prefix mit- is the most explicitly relational and democratic of these three spatial prefixes. Where an- emphasizes direction and bei- emphasizes proximity, mit- emphasizes integration and shared action. The word Mitleid (compassion/sympathy) is a perfect example: it captures the German understanding that true compassion is not feeling pity FOR someone, but suffering WITH them, standing alongside them in their pain. This word structure reveals how the language encodes a particular moral stance: empathy as shared experience, not pity as superiority. When you mitmachen (participate), you are not helping from outside; you are making WITH others, your actions mingled with theirs. The prefix makes the togetherness explicit, unavoidable, central to the meaning.

The key insight: mit- is about TOGETHERNESS, about SHARED ACTION, about STANDING ALONGSIDE. Whether you are participating (mitmachen), taking someone along (mitnehmen), being a member (Mitglied), or showing compassion (Mitleid), the prefix carries this sense of integration and mutual participation.

Anfangen /ˈanfaŋən/
to begin — to start; to commence an action or activity
DEU an- + fangen — at, toward + to catch, to seize — you grab at the beginning
ENG — English uses "begin" (Old English beginnan) with a different prefix
ZHO 开始 — kāishǐ (open + begin) — to open and thus begin
Anfangen literally means "to catch at" or "to grab at." The spatial prefix an- (at, toward) combines with fangen (to catch) to create the verb for beginning. The image is vivid: you reach out and seize the beginning of an action, grabbing at its start. The spatial becomes temporal.
Ankommen /ˈanˌkɔmən/
to arrive — to reach a destination; to come to a place
DEU an- + kommen — at, toward + to come — you come toward a specific place
ENG come — Old English "cuman"; German adds the directional prefix
ZHO 到达 — dàodá (arrive + reach) — reaching a destination
Ankommen is "to arrive" — literally "to come at." The prefix an- directs the coming toward a specific destination. You are not just wandering; you are moving with intention toward a point in space. This spatial directionality is what makes "ankommen" different from simply "kommen" (to come). The direction is built into the word.
Anrufen /ˈanˌruːfən/
to call — to telephone; to shout toward someone
DEU an- + rufen — at, toward + to call, to shout — you call at someone
ENG call — Old Norse "kalla"; Germanic root; English lost the prefix form
ZHO 打电话 — dǎ diànhuà (hit/make + telephone) — more mechanical than the German image
Anrufen is "to call" or "to telephone" — literally "to call at." The prefix an- directs your voice toward a specific person. When you call someone, you are not shouting into the void; you are targeting your voice at them, establishing directed contact. The spatial image of directional targeting survives in the modern word for "telephone."
Beibringen /ˈbaɪ̯ˌbʁɪŋən/
to teach — to instruct someone; to bring knowledge to someone
DEU bei- + bringen — by, near, with + to bring — you bring knowledge near
ENG bring — Old English "bringan"; German uses the prefix to make the teaching sense explicit
ZHO — jiào (to teach) — more direct, without the spatial image
Beibringen is "to teach" — literally "to bring near" or "to bring alongside." Teaching, in this view, is not imposing knowledge from above but bringing it within reach, placing it alongside someone so they can access it. The proximity image is central: knowledge brought close enough to touch and understand.
Beitragen /ˈbaɪ̯ˌtʁaːɡən/
to contribute — to give or add something to a common cause; to help bring about
DEU bei- + tragen — by, alongside + to carry, to bear — you carry alongside others
ENG carry — Old English "cierran"; both mean to bear or carry
ZHO 贡献 — gòngxiàn (tribute + dedicate) — to offer something formal
Beitragen is "to contribute" — literally "to carry alongside." When you contribute to a project, you are not leading the charge; you are walking beside others, bearing weight together with them. The image of shared labor, of walking alongside, is embedded in the word's structure.
Beispiel /ˈbaɪ̯ʃpiːl/
example — a thing characteristic of its kind or illustrating a general rule; something that demonstrates a concept
DEU bei- + Spiel — by, near, alongside + play, game — something played alongside the concept
ENG example — from Latin exemplum; Germanic roots lost in English translation
ZHO 例子 — lìzi (example + item) — something that exemplifies
Beispiel is the word for "example" — literally "something played alongside." An example is a game or play shown next to the main concept, illuminating it through proximity and analogy. The word itself is a fossil of ancient spatial thinking: an example is not separate from what it illustrates; it is positioned nearby, within the sphere of the concept it explains.
Mitmachen /ˈmɪtˌmaxən/
to participate — to take part in something; to join in an activity
DEU mit- + machen — with, together + to make, to do — you make alongside others
ENG make — Old English "macian"; English lost the productive prefix form
ZHO 参加 — cānjiā (join + add) — to add yourself to a collective action
Mitmachen is "to participate" — literally "to make with." When you participate, you are not helping from outside; you are making alongside others, your actions mingled with theirs, your presence integrated into the collective effort. The prefix makes the togetherness central and unavoidable.
Mitnehmen /ˈmɪtˌneːmən/
to take along — to bring someone or something with you; to include in a trip or activity
DEU mit- + nehmen — with, together + to take — you take something with you
ENG take — Old English "tacan"; both languages use the same root, German adds direction
ZHO 带上 — dàishang (carry + on) — to carry something along
Mitnehmen is "to take along" — literally "to take with." When you take someone with you, you include them in your journey. The prefix transforms a solitary action (taking) into a shared action (taking-along, including). The togetherness is the point of the word.
Mitglied /ˈmɪtɡliːt/
member — a person who belongs to a group, organization, or family
DEU mit- + Glied — with, together + limb, member — a limb that functions with the body
ENG member — from Latin membrum; English uses a different root
ZHO 成员 — chéngyuán (become + member) — one who becomes part of a group
Mitglied is "member" — literally "with-limb." A member is a limb that functions with the body, a part integrated into and functioning as part of a larger organism. You are not an independent appendage; you are a limb connected to and serving the whole. The ancient image of the body politic survives in this word.
Mitleid /ˈmɪtlaɪt/
compassion — sympathetic concern for the sufferings of others; the feeling of suffering with another
DEU mit- + Leid — with, together + suffering, sorrow — suffering together with another
ENG pity — from Latin pietas; different conceptual foundation
ZHO 同情 — tóngqíng (same + feeling) — feeling that is the same as another's
Mitleid is "compassion" — literally "with-suffering" or "suffering together." This word captures something profound: true compassion is not pity from above, not judgment of someone else's pain. It is standing alongside someone in their suffering, feeling their feeling, experiencing their burden alongside them. The prefix makes this explicit: you suffer WITH them, your pain aligned with theirs.
· · ·

Now let us look at what Chinese does with similar concepts. The Chinese language does not use prefixes in the way that German does. It is largely non-inflectional. But it builds similar ideas of directionality, proximity, and togetherness through different grammatical means — through word order, through aspectual particles, through the choice of which verb to use.

The word 参加 (cānjiā) in Chinese means "to participate." It is built from two characters: 参 (cān) meaning "to join, to attend" and 加 (jiā) meaning "to add, to join." The concept is spatial and relational: you are adding yourself to a situation, joining a group. The German mitmachen and the Chinese 参加 arrive at the same idea through different paths: participation as joining, as adding oneself to a collective action.

The word 同情 (tóngqíng) in Chinese means "sympathy" or "compassion." It is built from two characters: 同 (tóng) meaning "same" and 情 (qíng) meaning "feeling, emotion." So "compassion" in Chinese is literally "same-feeling," the feeling that is the same as another's. The German Mitleid (with-suffering) and the Chinese 同情 (same-feeling) are describing the same human experience from slightly different angles, but both encode the essential idea that compassion means emotional alignment with another person.

This is one of the great wonders of comparative linguistics: different languages, with completely different grammatical systems, with different ways of building words, can still converge on the same conceptual insights. The spatial and relational thinking that German encodes in its prefixes, Chinese encodes through other means. But both languages recognize that compassion is not an external judgment; it is a shared emotional state.

· · ·

By now, you can recognize these prefixes in many common German words. Look at the list below. For each word, the spatial prefix is there, working silently, transforming the root verb into a new meaning. The spatial has become the abstract. The preposition has become a tool for building verbs.

Anfangen — to begin [an- (at, toward) + fangen (to catch)] — you grab at the beginning

Ankommen — to arrive [an- (at, toward) + kommen (to come)] — you come at your destination

Anrufen — to call, to phone [an- (at, toward) + rufen (to call)] — you call at someone

Beibringen — to teach [bei- (by, near) + bringen (to bring)] — you bring knowledge near

Beitragen — to contribute [bei- (by, near) + tragen (to carry)] — you carry alongside others

Beispiel — example [bei- (by, near) + Spiel (play/game)] — a game played nearby, shown alongside

Mitmachen — to participate [mit- (with) + machen (to make)] — you make with others

Mitnehmen — to take along [mit- (with) + nehmen (to take)] — you take together with someone

Mitglied — member [mit- (with) + Glied (limb)] — a limb that functions with others

Mitleid — compassion [mit- (with) + Leid (suffering)] — suffering together with another

· · ·

Here is the profound insight: German took three ancient spatial prepositions (at, by, with) and used them as tools to create hundreds of different verbs from simple roots. The spatial thinking became abstract thinking. The concrete experience of standing in relation to others became the grammar for expressing action, participation, and emotional alignment.

When you learn German, you are not just learning a new language. You are learning a particular way of thinking about space, about relationship, about how actions connect to locations and to other people. These prefixes are so fundamental, so basic, that they shape how German speakers perceive and describe the world.

A German speaker saying "Ich nehme dich mit" (I take you with) is making something explicit that English speakers must infer. The prefix mit- is there in the word itself, inseparable, undeniable. You are not simply being taken somewhere; you are being taken ALONG, your presence is built into the verb structure itself.

This is the power of prefixes. They are not optional decorations on verbs. They are fundamental tools that transform meaning, that encode relationships, that make explicit what other languages must explain through context and word order. Three rivers — three spatial concepts — flowing together into thousands of verbs, carrying the sediment of ancient human thought about how we stand in relation to each other and to the world.

· · ·

Spatial prefixes are not abstractions from a linguist's textbook. They are pictures. They are concrete images that German speakers carry in their minds when they use these words.

An- is a vector pointing toward a target. Anfangen is reaching for the beginning. Ankommen is a path leading to a destination. Anrufen is a voice directed at someone across distance.

Bei- is a figure standing next to another. Beibringen is bringing knowledge close enough to touch. Beitragen is walking alongside, adding your effort to a collective task. Beispiel is a picture painted next to the main concept, illuminating it by proximity and analogy.

Mit- is hands held, arms linked, hearts intertwined. Mitmachen is dancing together. Mitnehmen is moving forward with someone you choose not to leave behind. Mitglied is a body in which each limb knows itself as part of a whole. Mitleid is two people breathing the same sorrow, sharing the same pain.

These images are not just poetic. They are the actual thinking patterns that the language preserves. When you understand the spatial meaning of these prefixes, you understand not just the grammar, but the worldview embedded in the grammar itself.

· · ·

How does a preposition become a prefix? The transformation is not sudden. It is gradual, hidden, a process that happens over centuries of language use.

In very old Germanic, these spatial words were used as prepositions. They came before nouns: "an der Wand" (on the wall), "bei dem Haus" (by the house), "mit dem Freund" (with the friend). But as German evolved, speakers began to attach these prepositions directly to verbs. A phrase like "an fangen" (to catch at) gradually merged into "anfangen" (to begin). What was once two words became one word. What was once a grammatical phrase became a prefix.

This is called grammaticalization, and it is one of the fundamental processes by which languages change and evolve. Words lose their independence, become bound to other words, transform their meaning as they transform their position in the sentence structure.

The same process happened in English and other Germanic languages, but to a lesser degree. English has largely lost its productive prefix system. We still have remnants: "a-" in "arise," "awake," but these are fossilized, no longer productive tools for building new words. German, by contrast, has kept these prefixes alive and vigorous. A German speaker can understand a new word built with an- or mit- instantly, because the prefix-verb system is still a living, breathing tool.

· · ·

This chapter is titled "The Beginning" for a reason. These three spatial prefixes are only the beginning. In the chapters ahead, you will encounter more prefixes: vor- (before), nach- (after), über- (over), unter- (under), and others. Each one carries its own spatial meaning. Each one has transformed its ancient preposional meaning into an abstract tool for building verbs.

But before you move on, understand this: the three prefixes you have learned in this chapter are among the most fundamental in German. They appear in hundreds of common words. They encode basic spatial relationships that every human understands: there is a target (an-), there is proximity (bei-), there is togetherness (mit-). These are not abstract grammatical concepts. These are pictures of how we stand in relation to others and to the world.

The ancient Indo-European speakers who created these words were thinking spatially, thinking about their bodies moving through space, thinking about how to express their relationship to other people and to the objects around them. That thinking, encoded in these prefixes, is still alive in German today, still shaping how German speakers understand and describe reality.

When you master these three prefixes, you will recognize them in countless German words. When you understand the spatial thinking behind them, you will understand not just the grammar, but a whole way of thinking about the world.

· · ·
Patterns Discovered
Spatial Prefixes Becoming Temporal and Abstract — An-, bei-, and mit- begin as prepositions expressing location in space. As prefixes, they transform these spatial concepts into temporal (anfangen = begin), relational (beibringen = teach), and participatory (mitmachen = participate) meanings. Spatial thinking becomes the foundation for abstract reasoning.

Three Directional Orientations — An- points toward a location or target (at, toward). Bei- expresses proximity and accompanying presence (by, near, alongside). Mit- embodies joint participation and togetherness (with). Together, they map three different relations between an agent and others or a destination.

Inseparability and Productivity — Unlike auf- and aus-, the prefixes an-, bei-, and mit- are inseparable: they do not detach during conjugation. This stability allows them to be highly productive with new verb formations. The prefix remains bound, making new compounds completely transparent to speakers.

Ancient Spatial Logic Preserved — These prefixes are among the oldest elements of Germanic. Their survival and productivity reveals how foundational spatial thinking is to language. Even modern German speakers, unaware of the etymology, unconsciously follow the ancient spatial logic encoded in these three directions.
Your Progress
Words Collected 393 / 850 (46%)
Click to see all words ▾
Patterns & Grammar 89 / 145 (61%)
Click to see all patterns ▾

Words from Der Anfang (The Beginning)

anfangen
begin
ankommen
arrive
anrufen
call
beibringen
teach
beitragen
contribute
Beispiel
example
mitmachen
participate
mitnehmen
take along
Mitglied
member
Mitleid
compassion

Check Your Understanding

Test your mastery of Der Anfang. 80% required to continue.

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: "I arrive tomorrow"
Available words:
Build: "We participate together"
Available words:
Build: "She teaches the children"
Available words:
2 Lückensatz — Gap Sentence
Fill in the blank: "Ich _______ morgen an." (I ___ tomorrow.)
Fill in the blank: "Wir _______ heute mit." (We ___ today.)
Fill in the blank: "Die Lehrerin _______ den Schülern Deutsch." (The teacher ___ German to the students.)
Fill in the blank: "Dein _______ ist wichtig." (Your ___ is important.)
3 Freies Bauen — Free Building
Translate to German: "to arrive"
Translate to German: "to begin"
Translate to German: "to participate"
Translate to German: "member"
Your Progress: 0 / 12 Correct

Lesen & Hören — Read and Listen

Jedes Jahr fängt mit einer neuen Hoffnung an.
Die Lehrer bringen ihren Schülern wichtige Lektionen bei.
Wir tragen alle zu einem gemeinsamen Ziel bei.
Mein Freund kommt morgen an und macht mit uns die Arbeit.
Ein Beispiel zeigt uns den richtigen Weg.
Das Mitglied bringt seine Mitleid für andere zum Ausdruck.

Verständnisfragen — Comprehension Questions

1. What was the main theme discussed?
The prefixes and their meanings
A story about travel
A lesson about numbers
2. What action was described?
Multiple actions using the chapter prefixes
Only one action
No action was described
3. Fill in: "Mein Freund _____ morgen an."
4. Did the passage use separable or inseparable prefixes?
Both, depending on the prefix
Only separable
Only inseparable

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
/* === 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(); });