Files
cluster-state/apps/nihongo/configmap.yaml
2026-07-21 20:30:18 +02:00

1052 lines
90 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
apiVersion: v1
kind: ConfigMap
metadata:
name: nihongo-html
namespace: nihongo
data:
index.html: |
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kody Sensei — CM_7-5 Übung</title>
<style>
:root{
--orange:#f2c58a; --orange-d:#e6a94f; --ink:#4a4a4a; --ink-soft:#6d6d6d;
--blue:#2f7fd6; --wo:#c0392b; --green:#2e8b57; --bg:#fbf7f0; --card:#fff;
--line:#ece3d5; --shadow:0 4px 18px rgba(0,0,0,.08);
}
*{box-sizing:border-box}
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Noto Sans JP",sans-serif;
background:var(--bg);color:var(--ink);line-height:1.55}
header{background:var(--orange);padding:14px 20px;display:flex;align-items:center;gap:12px;
box-shadow:var(--shadow);position:sticky;top:0;z-index:10}
header .dog{font-size:28px}
header h1{font-size:17px;margin:0;font-weight:800;color:#555}
header .sub{font-size:12px;color:#7a5b1e;margin-top:2px}
.wrap{max-width:660px;margin:0 auto;padding:18px}
nav{display:flex;gap:8px;margin-bottom:18px;flex-wrap:wrap}
.lessonbar{display:flex;align-items:center;gap:10px;margin-bottom:12px;background:#fff;
border-radius:12px;box-shadow:var(--shadow);padding:10px 14px}
.lessonbar label{font-size:13px;font-weight:700;color:var(--ink-soft);white-space:nowrap}
.lessonbar select{flex:1}
nav button{flex:1;min-width:84px;border:none;border-radius:12px;padding:10px 6px;font-size:13px;
font-weight:700;cursor:pointer;background:#fff;color:var(--ink-soft);box-shadow:var(--shadow);
transition:.15s}
nav button.active{background:var(--orange-d);color:#fff}
.card{background:var(--card);border-radius:18px;box-shadow:var(--shadow);padding:26px 22px;margin-bottom:16px}
.prompt-label{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--orange-d);
font-weight:800;margin-bottom:8px}
.de{font-size:21px;font-weight:600}
.en{font-size:14px;color:var(--ink-soft);margin-top:4px;font-style:italic}
.q{font-size:13px;color:var(--orange-d);font-weight:700;margin-top:8px}
.jp{font-size:30px;margin:16px 0 6px;font-weight:600}
.jp ruby rt{font-size:.5em;color:var(--ink-soft);font-weight:400}
.reading{font-size:16px;color:var(--ink-soft)}
.hidden{display:none}
.btn{display:inline-block;border:none;border-radius:12px;padding:13px 20px;font-size:15px;font-weight:700;
cursor:pointer;transition:.12s}
.btn:active{transform:translateY(1px)}
.btn-primary{background:var(--orange-d);color:#fff;width:100%}
.btn-row{display:flex;gap:10px;margin-top:16px}
.btn-ok{background:var(--green);color:#fff;flex:1}
.btn-no{background:var(--wo);color:#fff;flex:1}
.p-ni{color:var(--blue);font-weight:800}
.p-wo{color:var(--wo);font-weight:800}
.p-de{color:#8e44ad;font-weight:800}
.p-ga{color:#2e8b57;font-weight:800}
.p-wa{color:#b8860b;font-weight:800}
.p-mo{color:#0d9488;font-weight:800}
.grammarnote{background:#fff;border-radius:12px;box-shadow:var(--shadow);padding:12px 16px;margin-bottom:14px;
font-size:14px;border-left:4px solid var(--orange-d)}
.grammarnote b{color:var(--orange-d)}
.progress{height:8px;background:#eee;border-radius:99px;overflow:hidden;margin-bottom:14px}
.progress > div{height:100%;background:var(--orange-d);width:0;transition:.3s}
.meta{display:flex;justify-content:space-between;font-size:13px;color:var(--ink-soft);margin-bottom:14px}
.note{font-size:13px;color:var(--ink-soft);background:#fbf3e4;border-left:4px solid var(--orange-d);
padding:10px 14px;border-radius:8px;margin-top:14px;line-height:1.5}
.blanks{font-size:26px;line-height:2.1;margin:14px 0}
.slot{display:inline-block;min-width:46px;border-bottom:3px solid var(--orange-d);text-align:center;
cursor:pointer;color:#bbb}
.slot.filled{color:var(--ink);border-color:var(--green)}
.choices{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
.choices button{border:2px solid var(--line);background:#fff;border-radius:10px;padding:8px 16px;
font-size:20px;cursor:pointer;font-weight:700}
.feedback{margin-top:14px;font-weight:700}
.done{text-align:center;padding:30px}
.done .big{font-size:44px}
.barctl{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;gap:10px}
select.sel{border:2px solid var(--line);border-radius:10px;padding:6px 10px;font-size:13px;background:#fff;color:var(--ink)}
.tip{font-size:12px;color:var(--ink-soft);text-align:center;margin-top:8px}
input.type{width:100%;font-size:22px;padding:12px 14px;border:2px solid var(--line);border-radius:12px;
margin-top:14px;text-align:center;font-family:inherit}
input.type:focus{outline:none;border-color:var(--orange-d)}
input.type.ok{border-color:var(--green);background:#f0fbf4}
input.type.bad{border-color:var(--wo);background:#fdf0ee}
.boxes{display:inline-flex;gap:3px;vertical-align:middle;margin-left:6px}
.boxes i{width:8px;height:8px;border-radius:2px;background:#e2d8c8}
.boxes i.on{background:var(--orange-d)}
.phrase{background:#fff;border-radius:14px;box-shadow:var(--shadow);padding:14px 16px;margin-bottom:10px}
.phrase .jp{font-size:22px;margin:0 0 2px}
.phrase .reading{font-size:13px}
.phrase .de{font-size:15px;color:var(--ink);margin-top:4px;font-weight:500}
h2.section{font-size:16px;color:var(--orange-d);margin:22px 0 10px}
ul.beh{padding-left:18px;margin:0}
ul.beh li{margin-bottom:8px;font-size:14px}
.tiles{display:flex;gap:10px;margin-bottom:6px}
.tile{flex:1;background:#fff;border-radius:14px;box-shadow:var(--shadow);padding:16px 10px;text-align:center}
.tile b{display:block;font-size:26px;color:var(--orange-d)}
.tile span{font-size:12px;color:var(--ink-soft)}
.row{display:flex;align-items:center;justify-content:space-between;background:#fff;border-radius:12px;
box-shadow:var(--shadow);padding:10px 14px;margin-bottom:8px;gap:10px}
.row .lbl{font-size:17px}
.row .rt{font-size:13px;color:var(--ink-soft);white-space:nowrap}
.row .rt .ok{color:var(--green);font-weight:700}
.row .rt .bad{color:var(--wo);font-weight:700}
.btn-reset{background:#f0ece4;color:var(--ink-soft);width:100%;margin-top:8px}
.empty{text-align:center;color:var(--ink-soft);padding:26px}
</style>
</head>
<body>
<header>
<span class="dog">🐕</span>
<div><h1>CM_7-5 · The Purpose of Movement</h1>
<div class="sub">Kody Sensei — Übung für Dominik · ~に ~を ~に いきます</div></div>
</header>
<div class="wrap">
<div class="lessonbar">
<label for="lessonSel">📚 Lektion</label>
<select id="lessonSel" class="sel"></select>
</div>
<nav>
<button data-mode="review" class="active">🔁 Wiederholen</button>
<button data-mode="stats">📊 Fortschritt</button>
<button data-mode="unterricht">🗣️ Unterricht</button>
<button data-mode="vocab">📇 Vokabeln</button>
<button data-mode="verbstem">🔀 ますStamm</button>
<button data-mode="adj">🔤 Adjektiv</button>
<button data-mode="sentence">✍️ Satzbau</button>
<button data-mode="particle">🧩 Partikel</button>
</nav>
<div id="grammarNote" class="grammarnote" style="display:none"></div>
<div class="progress"><div id="bar"></div></div>
<div class="meta"><span id="counter"></span><span id="score"></span></div>
<div id="app"></div>
</div>
<script>
/* ================= DATEN ================= */
const VOCAB = [
{jpr:'<ruby>食<rt>た</rt></ruby>べる', read:"たべる(たべます)", de:"essen", en:"to eat", kana:"たべる"},
{jpr:'<ruby>飲<rt>の</rt></ruby>む', read:"のむ(のみます)", de:"trinken", en:"to drink", kana:"のむ"},
{jpr:'<ruby>作<rt>つく</rt></ruby>る', read:"つくる(つくります)", de:"machen / kochen", en:"to make", kana:"つくる"},
{jpr:'<ruby>行<rt>い</rt></ruby>く', read:"いく(いきます)", de:"gehen", en:"to go", kana:"いく"},
{jpr:'<ruby>働<rt>はたら</rt></ruby>く', read:"はたらく(はたらきます)", de:"arbeiten", en:"to work", kana:"はたらく"},
{jpr:'<ruby>掃除<rt>そうじ</rt></ruby>する', read:"そうじする(そうじします)", de:"putzen / saubermachen", en:"to clean", kana:"そうじする"},
{jpr:'<ruby>仕事<rt>しごと</rt></ruby>', read:"しごと", de:"Arbeit / Job", en:"work, job", kana:"しごと"},
{jpr:'<ruby>地下室<rt>ちかしつ</rt></ruby>', read:"ちかしつ", de:"Keller", en:"basement", kana:"ちかしつ"},
{jpr:'<ruby>晩<rt>ばん</rt></ruby>ご<ruby>飯<rt>はん</rt></ruby>', read:"ばんごはん", de:"Abendessen", en:"dinner", kana:"ばんごはん"},
{jpr:'ラーメン', read:"らーめん", de:"Ramen", en:"ramen", kana:"らーめん"},
{jpr:'<ruby>抹茶<rt>まっちゃ</rt></ruby>', read:"まっちゃ", de:"Matcha", en:"matcha", kana:"まっちゃ"},
{jpr:'コーヒー', read:"こーひー", de:"Kaffee", en:"coffee", kana:"こーひー"},
{jpr:'カフェ', read:"かふぇ", de:"Café", en:"café", kana:"かふぇ"},
{jpr:'レストラン', read:"れすとらん", de:"Restaurant", en:"restaurant", kana:"れすとらん"},
{jpr:'<ruby>家<rt>うち</rt></ruby>', read:"うち", de:"Zuhause", en:"home", kana:"うち"},
{jpr:'<ruby>昨日<rt>きのう</rt></ruby>', read:"きのう", de:"gestern", en:"yesterday", kana:"きのう"},
{jpr:'<ruby>時々<rt>ときどき</rt></ruby>', read:"ときどき", de:"manchmal", en:"sometimes", kana:"ときどき"},
{jpr:'<ruby>毎朝<rt>まいあさ</rt></ruby>', read:"まいあさ", de:"jeden Morgen", en:"every morning", kana:"まいあさ"},
{jpr:'<ruby>毎晩<rt>まいばん</rt></ruby>', read:"まいばん", de:"jeden Abend", en:"every night", kana:"まいばん"},
{jpr:'ちなみに', read:"ちなみに", de:"übrigens", en:"by the way", kana:"ちなみに"},
{jpr:'きれい', read:"きれい", de:"sauber / schön", en:"clean, pretty", kana:"きれい"},
];
const VERBS = [
{jpr:'<ruby>食<rt>た</rt></ruby>べる', de:"essen", group:"Gruppe 2 (ru-Verb)", stemr:'<ruby>食<rt>た</rt></ruby>べ', stemKana:"たべ", masur:'<ruby>食<rt>た</rt></ruby>べます', rule:"ru-Verb: einfach る weg → たべ"},
{jpr:'<ruby>見<rt>み</rt></ruby>る', de:"sehen", group:"Gruppe 2 (ru-Verb)", stemr:'<ruby>見<rt>み</rt></ruby>', stemKana:"み", masur:'<ruby>見<rt>み</rt></ruby>ます', rule:"ru-Verb: る weg → み"},
{jpr:'<ruby>飲<rt>の</rt></ruby>む', de:"trinken", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>飲<rt>の</rt></ruby>み', stemKana:"のみ", masur:'<ruby>飲<rt>の</rt></ruby>みます', rule:"u-Verb: む → み"},
{jpr:'<ruby>作<rt>つく</rt></ruby>る', de:"machen", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>作<rt>つく</rt></ruby>り', stemKana:"つくり", masur:'<ruby>作<rt>つく</rt></ruby>ります', rule:"u-Verb: る → り"},
{jpr:'<ruby>行<rt>い</rt></ruby>く', de:"gehen", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>行<rt>い</rt></ruby>き', stemKana:"いき", masur:'<ruby>行<rt>い</rt></ruby>きます', rule:"u-Verb: く → き"},
{jpr:'<ruby>働<rt>はたら</rt></ruby>く', de:"arbeiten", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>働<rt>はたら</rt></ruby>き', stemKana:"はたらき", masur:'<ruby>働<rt>はたら</rt></ruby>きます', rule:"u-Verb: く → き"},
{jpr:'<ruby>話<rt>はな</rt></ruby>す', de:"sprechen", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>話<rt>はな</rt></ruby>し', stemKana:"はなし", masur:'<ruby>話<rt>はな</rt></ruby>します', rule:"u-Verb: す → し"},
{jpr:'<ruby>買<rt>か</rt></ruby>う', de:"kaufen", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>買<rt>か</rt></ruby>い', stemKana:"かい", masur:'<ruby>買<rt>か</rt></ruby>います', rule:"u-Verb: う → い"},
{jpr:'<ruby>帰<rt>かえ</rt></ruby>る', de:"heimgehen", group:"Gruppe 1 (Ausnahme!)", stemr:'<ruby>帰<rt>かえ</rt></ruby>り', stemKana:"かえり", masur:'<ruby>帰<rt>かえ</rt></ruby>ります', rule:"Sieht aus wie ru-Verb, ist aber u-Verb: る → り"},
{jpr:'<ruby>掃除<rt>そうじ</rt></ruby>する', de:"putzen", group:"Gruppe 3 (suru)", stemr:'<ruby>掃除<rt>そうじ</rt></ruby>し', stemKana:"そうじし", masur:'<ruby>掃除<rt>そうじ</rt></ruby>します', rule:"する-Verb: する → し"},
];
const SENTENCES = [
{de:"Ich gehe nach Yokohama, um Ramen zu essen.", en:"I'll go to Yokohama to eat ramen.",
r:'<ruby>横浜<rt>よこはま</rt></ruby><span class="p-ni">に</span> ラーメン<span class="p-wo">を</span> <ruby>食<rt>た</rt></ruby>べ<span class="p-ni">に</span> <ruby>行<rt>い</rt></ruby>きます。',
read:"よこはまに らーめんを たべに いきます。"},
{de:"Ich gehe nach Kyoto, um Matcha zu trinken.", en:"I'll go to Kyoto to drink matcha.",
r:'<ruby>京都<rt>きょうと</rt></ruby><span class="p-ni">に</span> <ruby>抹茶<rt>まっちゃ</rt></ruby><span class="p-wo">を</span> <ruby>飲<rt>の</rt></ruby>み<span class="p-ni">に</span> <ruby>行<rt>い</rt></ruby>きます。',
read:"きょうとに まっちゃを のみに いきます。"},
{de:"Gehst du (manchmal) ins Café, um Kaffee zu trinken?", en:"Do you go to a café to drink coffee?",
r:'カフェ<span class="p-ni">に</span> コーヒー<span class="p-wo">を</span> <ruby>飲<rt>の</rt></ruby>み<span class="p-ni">に</span> いきますか。',
read:"かふぇに こーひーを のみに いきますか。"},
{de:"Gehst du (manchmal) ins Restaurant, um Abendessen zu essen?", en:"Do you go to a restaurant to eat dinner?",
r:'レストラン<span class="p-ni">に</span> <ruby>晩<rt>ばん</rt></ruby>ごはん<span class="p-wo">を</span> <ruby>食<rt>た</rt></ruby>べ<span class="p-ni">に</span> いきますか。',
read:"れすとらんに ばんごはんを たべに いきますか。"},
{de:"Aber jeden Morgen trinke ich zu Hause Kaffee.", en:"But every morning I drink coffee at home.",
r:'でも <ruby>毎朝<rt>まいあさ</rt></ruby> うち<span class="p-de">で</span> コーヒー<span class="p-wo">を</span> <ruby>飲<rt>の</rt></ruby>みます。',
read:"でも まいあさ うちで こーひーを のみます。"},
{de:"Aber jeden Abend koche ich zu Hause das Abendessen.", en:"But every night I make dinner at home.",
r:'でも <ruby>毎晩<rt>まいばん</rt></ruby> うち<span class="p-de">で</span> <ruby>晩<rt>ばん</rt></ruby>ごはん<span class="p-wo">を</span> <ruby>作<rt>つく</rt></ruby>ります。',
read:"でも まいばん うちで ばんごはんを つくります。"},
{de:"Was hast du gestern gemacht?", en:"What did you do yesterday?",
r:'<ruby>昨日<rt>きのう</rt></ruby> <ruby>何<rt>なに</rt></ruby><span class="p-wo">を</span> しましたか。',
read:"きのう なにを しましたか。"},
{de:"Ich bin zur Arbeit gegangen und habe gearbeitet.", en:"I went to work and worked.",
r:'<ruby>仕事<rt>しごと</rt></ruby><span class="p-ni">に</span> <ruby>行<rt>い</rt></ruby>って <ruby>働<rt>はたら</rt></ruby>きました。',
read:"しごとに いって はたらきました。"},
{de:"Dann habe ich den Keller sauber geputzt.", en:"Then I cleaned the basement.",
r:'そして <ruby>地下室<rt>ちかしつ</rt></ruby><span class="p-wo">を</span> そうじしました。',
read:"そして ちかしつを そうじしました。"},
];
const PHRASES = [
{jpr:'お<ruby>願<rt>ねが</rt></ruby>いします。', read:"おねがいします", de:"Bitte. (allgemeine Bitte)"},
{jpr:'よろしくお<ruby>願<rt>ねが</rt></ruby>いします。', read:"よろしくおねがいします", de:"Bitte um gute Zusammenarbeit (zu Beginn)."},
{jpr:'もう<ruby>一度<rt>いちど</rt></ruby>お<ruby>願<rt>ねが</rt></ruby>いします。', read:"もういちどおねがいします", de:"Noch einmal, bitte."},
{jpr:'ゆっくりお<ruby>願<rt>ねが</rt></ruby>いします。', read:"ゆっくりおねがいします", de:"Langsamer, bitte."},
{jpr:'もう<ruby>少<rt>すこ</rt></ruby>しゆっくり<ruby>話<rt>はな</rt></ruby>してください。', read:"もうすこしゆっくりはなしてください", de:"Bitte sprich etwas langsamer."},
{jpr:'すみません、わかりません。', read:"すみません、わかりません", de:"Entschuldigung, ich verstehe nicht."},
{jpr:'わかりました。', read:"わかりました", de:"Ich habe verstanden."},
{jpr:'〜は<ruby>日本語<rt>にほんご</rt></ruby>で<ruby>何<rt>なん</rt></ruby>ですか。', read:"〜はにほんごでなんですか", de:"Wie heißt … auf Japanisch?"},
{jpr:'〜はどういう<ruby>意味<rt>いみ</rt></ruby>ですか。', read:"〜はどういういみですか", de:"Was bedeutet …?"},
{jpr:'これはどう<ruby>読<rt>よ</rt></ruby>みますか。', read:"これはどうよみますか", de:"Wie liest man das?"},
{jpr:'<ruby>質問<rt>しつもん</rt></ruby>があります。', read:"しつもんがあります", de:"Ich habe eine Frage."},
{jpr:'もう<ruby>一度<rt>いちど</rt></ruby><ruby>言<rt>い</rt></ruby>ってください。', read:"もういちどいってください", de:"Bitte sag es noch einmal."},
{jpr:'<ruby>例<rt>れい</rt></ruby>をお<ruby>願<rt>ねが</rt></ruby>いします。', read:"れいをおねがいします", de:"Ein Beispiel, bitte."},
{jpr:'ちょっと<ruby>待<rt>ま</rt></ruby>ってください。', read:"ちょっとまってください", de:"Einen Moment, bitte."},
{jpr:'<ruby>大丈夫<rt>だいじょうぶ</rt></ruby>です。', read:"だいじょうぶです", de:"Alles gut / passt."},
{jpr:'<ruby>宿題<rt>しゅくだい</rt></ruby>は<ruby>何<rt>なん</rt></ruby>ですか。', read:"しゅくだいはなんですか", de:"Was ist die Hausaufgabe?"},
{jpr:'ありがとうございました。', read:"ありがとうございました", de:"Vielen Dank! (am Ende)"},
{jpr:'また<ruby>来週<rt>らいしゅう</rt></ruby>。', read:"またらいしゅう", de:"Bis nächste Woche."},
{jpr:'ヒントおねがいします。', read:"ひんとおねがいします", de:"Bitte gib mir einen Tipp."},
{jpr:'〜は<ruby>何<rt>なん</rt></ruby>でしたっけ。', read:"〜はなんでしたっけ", de:"Wie war … noch mal?"},
];
const PARTICLES = [
{parts:['<ruby>横浜<rt>よこはま</rt></ruby>',"___","ラーメン","___",'<ruby>食<rt>た</rt></ruby>べ',"___",'<ruby>行<rt>い</rt></ruby>きます。'], ans:["に","を","に"], hint:"nach Yokohama, um Ramen zu essen"},
{parts:["カフェ","___","コーヒー","___",'<ruby>飲<rt>の</rt></ruby>み',"___","いきます。"], ans:["に","を","に"], hint:"ins Café, um Kaffee zu trinken"},
{parts:['まいあさ うち',"___","コーヒー","___",'<ruby>飲<rt>の</rt></ruby>みます。'], ans:["で","を"], hint:"Ort der Handlung, nicht Ziel!"},
{parts:['<ruby>京都<rt>きょうと</rt></ruby>',"___",'<ruby>抹茶<rt>まっちゃ</rt></ruby>',"___",'<ruby>飲<rt>の</rt></ruby>み',"___",'<ruby>行<rt>い</rt></ruby>きます。'], ans:["に","を","に"], hint:"nach Kyoto, um Matcha zu trinken"},
{parts:['<ruby>仕事<rt>しごと</rt></ruby>',"___",'<ruby>行<rt>い</rt></ruby>って <ruby>働<rt>はたら</rt></ruby>きました。'], ans:["に"], hint:"zur Arbeit gehen"},
{parts:['<ruby>地下室<rt>ちかしつ</rt></ruby>',"___","そうじしました。"], ans:["を"], hint:"das Objekt, das geputzt wird"},
];
const CHOICES = ["は","が","に","を","で","も","か"];
/* ================= LEKTIONEN (hier hängt Kody-san neue Lektionen an) ================= */
const LESSONS = [
/* ---------- CM_1-2 Question Sentences ---------- */
{id:'cm1-2', code:'CM_1-2', title:'Question Sentences',
grammar:'Fragen mit <b>~ですか</b> beantworten: <b>はい、そうです。</b> (ja) / <b>いいえ、ちがいます。</b> (nein).',
vocab:[
{jpr:'そうです', read:"そうです", de:"genau / so ist es", en:"that's right", kana:"そうです"},
{jpr:'ちがう', read:"ちがう(ちがいます)", de:"falsch / anders sein", en:"to be wrong", kana:"ちがう"},
{jpr:'<ruby>学生<rt>がくせい</rt></ruby>', read:"がくせい", de:"Student", en:"student", kana:"がくせい"},
{jpr:'エンジニア', read:"えんじにあ", de:"Ingenieur", en:"engineer", kana:"えんじにあ"},
{jpr:'はい', read:"はい", de:"ja", en:"yes", kana:"はい"},
{jpr:'いいえ', read:"いいえ", de:"nein", en:"no", kana:"いいえ"},
],
verbs:[],
sentences:[
{de:"Bist du DevOps-Engineer?", en:"Are you a DevOps engineer?", r:'Dさん<span class="p-wa">は</span> DevOps エンジニアですか。', read:"Dさんは DevOps えんじにあですか。"},
{de:"Ja, das stimmt.", en:"Yes, it is.", r:'はい、そうです。', read:"はい、そうです。"},
{de:"Bist du Student?", en:"Are you a student?", r:'Dさん<span class="p-wa">は</span> <ruby>学生<rt>がくせい</rt></ruby>ですか。', read:"Dさんは がくせいですか。"},
{de:"Nein, ich bin kein Student.", en:"No, I'm not a student.", r:'いいえ、<ruby>学生<rt>がくせい</rt></ruby>じゃないです。', read:"いいえ、がくせいじゃないです。"},
{de:"Nein, das stimmt nicht.", en:"No, that's not right.", r:'いいえ、ちがいます。', read:"いいえ、ちがいます。"},
],
particles:[
{parts:['Dさん',"___",'<ruby>学生<rt>がくせい</rt></ruby>ですか。'], ans:["は"], hint:"Themenpartikel"},
]},
/* ---------- CM_3-6 Frequency Adverbs ---------- */
{id:'cm3-6', code:'CM_3-6', title:'Frequency Adverbs',
grammar:'Häufigkeit: <b>ときどき</b> (manchmal) + V<b>ます</b> · <b>あんまり/あまり</b> (nicht sehr) + V<b>ません</b>.',
vocab:[
{jpr:'ときどき', read:"ときどき", de:"manchmal", en:"sometimes", kana:"ときどき"},
{jpr:'あんまり', read:"あんまり(あまり)", de:"nicht besonders", en:"not very", kana:"あんまり"},
{jpr:'ジム', read:"じむ", de:"Fitnessstudio", en:"gym", kana:"じむ"},
{jpr:'カレー', read:"かれー", de:"Curry", en:"curry", kana:"かれー"},
{jpr:'からい', read:"からい", de:"scharf", en:"spicy", kana:"からい"},
{jpr:'<ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby>', read:"たべもの", de:"Essen / Speise", en:"food", kana:"たべもの"},
{jpr:'<ruby>卵<rt>たまご</rt></ruby>', read:"たまご", de:"Ei", en:"egg", kana:"たまご"},
{jpr:'じゃがいも', read:"じゃがいも", de:"Kartoffel", en:"potato", kana:"じゃがいも"},
{jpr:'<ruby>塩<rt>しお</rt></ruby>', read:"しお", de:"Salz", en:"salt", kana:"しお"},
{jpr:'<ruby>料理<rt>りょうり</rt></ruby>', read:"りょうり", de:"Gericht / Küche", en:"dish, cooking", kana:"りょうり"},
{jpr:'ビール', read:"びーる", de:"Bier", en:"beer", kana:"びーる"},
{jpr:'<ruby>高<rt>たか</rt></ruby>い', read:"たかい", de:"teuer / hoch", en:"expensive", kana:"たかい"},
{jpr:'<ruby>好<rt>す</rt></ruby>き', read:"すき", de:"mögen", en:"to like", kana:"すき"},
],
verbs:[],
sentences:[
{de:"Ich gehe manchmal ins Fitnessstudio.", en:"I sometimes go to the gym.", r:'(わたし<span class="p-wa">は</span>)ときどき ジム<span class="p-ni">に</span> いきます。', read:"わたしは ときどき じむに いきます。"},
{de:"Isst du manchmal japanisches Essen?", en:"Do you sometimes eat Japanese food?", r:'Dさん<span class="p-wa">は</span> ときどき <ruby>日本<rt>にほん</rt></ruby>の <ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby><span class="p-wo">を</span> <ruby>食<rt>た</rt></ruby>べますか。', read:"Dさんは ときどき にほんの たべものを たべますか。"},
{de:"Ja, manchmal esse ich Curry.", en:"Yes, I sometimes eat curry.", r:'はい。ときどき カレー<span class="p-wo">を</span> <ruby>食<rt>た</rt></ruby>べます。', read:"はい。ときどき かれーを たべます。"},
{de:"Magst du scharfes Essen?", en:"Do you like spicy food?", r:'からい <ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby><span class="p-ga">が</span> <ruby>好<rt>す</rt></ruby>きですか。', read:"からい たべものが すきですか。"},
{de:"Ich gehe nicht oft ins Fitnessstudio.", en:"I don't go to the gym very often.", r:'(わたし<span class="p-wa">は</span>)あんまり ジム<span class="p-ni">に</span> いきません。', read:"わたしは あんまり じむに いきません。"},
{de:"Ich mag Bier, aber ich trinke nicht viel.", en:"I like beer, but I don't drink much.", r:'ビール<span class="p-ga">が</span> <ruby>好<rt>す</rt></ruby>きです。でも あんまり <ruby>飲<rt>の</rt></ruby>みません。', read:"びーるが すきです。でも あんまり のみません。"},
],
adjectives:[
{jpr:'からい', read:"からい", de:"scharf", type:'i', negr:'からくない', negKana:"からくない", rule:"い-Adj: い weg → くない"},
{jpr:'<ruby>高<rt>たか</rt></ruby>い', read:"たかい", de:"teuer / hoch", type:'i', negr:'<ruby>高<rt>たか</rt></ruby>くない', negKana:"たかくない", rule:"い-Adj: い weg → くない"},
],
particles:[
{parts:['ときどき ジム',"___",'いきます。'], ans:["に"], hint:"Bewegungsziel"},
{parts:['カレー',"___",'<ruby>食<rt>た</rt></ruby>べます。'], ans:["を"], hint:"Objekt"},
{parts:['からい <ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby>',"___",'<ruby>好<rt>す</rt></ruby>きです。'], ans:["が"], hint:"bei 好き steht が"},
{parts:['あんまり ジム',"___",'いきません。'], ans:["に"], hint:"Bewegungsziel"},
]},
/* ---------- CM_4-1 X があります ---------- */
{id:'cm4-1', code:'CM_4-1', title:'X があります (There is X)',
grammar:'<b>{Ort に}{Nomen が}{あります}</b> für Dinge · <b>{います}</b> für Lebewesen.',
vocab:[
{jpr:'<ruby>屋<rt>や</rt></ruby>', read:"や", de:"…-Laden (Suffix)", en:"shop", kana:"や"},
{jpr:'ラーメン<ruby>屋<rt>や</rt></ruby>', read:"らーめんや", de:"Ramen-Laden", en:"ramen shop", kana:"らーめんや"},
{jpr:'お<ruby>城<rt>しろ</rt></ruby>', read:"おしろ", de:"Burg / Schloss", en:"castle", kana:"おしろ"},
{jpr:'<ruby>町<rt>まち</rt></ruby>', read:"まち", de:"Stadt", en:"town", kana:"まち"},
{jpr:'<ruby>日本人<rt>にほんじん</rt></ruby>', read:"にほんじん", de:"Japaner", en:"Japanese person", kana:"にほんじん"},
{jpr:'たくさん', read:"たくさん", de:"viele / viel", en:"a lot", kana:"たくさん"},
{jpr:'ある', read:"ある(あります)", de:"es gibt (Dinge)", en:"there is (things)", kana:"ある"},
{jpr:'いる', read:"いる(います)", de:"es gibt (Lebewesen)", en:"there is (living)", kana:"いる"},
],
verbs:[],
sentences:[
{de:"In Yokohama gibt es einen Ramen-Laden.", en:"There is a ramen shop in Yokohama.", r:'<ruby>横浜<rt>よこはま</rt></ruby><span class="p-ni">に</span> ラーメン<ruby>屋<rt>や</rt></ruby><span class="p-ga">が</span> あります。', read:"よこはまに らーめんやが あります。"},
{de:"In Osaka gibt es eine Burg.", en:"There is a castle in Osaka.", r:'<ruby>大阪<rt>おおさか</rt></ruby><span class="p-ni">に</span> お<ruby>城<rt>しろ</rt></ruby><span class="p-ga">が</span> あります。', read:"おおさかに おしろが あります。"},
{de:"Auch in Deutschland gibt es Burgen.", en:"There are castles in Germany too.", r:'ドイツ<span class="p-ni">に</span>も お<ruby>城<rt>しろ</rt></ruby><span class="p-ga">が</span> あります。', read:"どいつにも おしろが あります。"},
{de:"Ja, es gibt viele Burgen.", en:"Yes, there are a lot of castles.", r:'はい。たくさん お<ruby>城<rt>しろ</rt></ruby><span class="p-ga">が</span> あります。', read:"はい。たくさん おしろが あります。"},
{de:"In meiner Stadt gibt es Japaner.", en:"There are Japanese people in my city.", r:'<ruby>私<rt>わたし</rt></ruby>の<ruby>町<rt>まち</rt></ruby><span class="p-ni">に</span> <ruby>日本人<rt>にほんじん</rt></ruby><span class="p-ga">が</span> います。', read:"わたしのまちに にほんじんが います。"},
],
particles:[
{parts:['<ruby>横浜<rt>よこはま</rt></ruby>',"___",'ラーメン<ruby>屋<rt>や</rt></ruby>',"___",'あります。'], ans:["に","が"], hint:"Ort に … が あります"},
{parts:['<ruby>大阪<rt>おおさか</rt></ruby>',"___",'お<ruby>城<rt>しろ</rt></ruby>',"___",'あります。'], ans:["に","が"], hint:"Ort に … が あります"},
{parts:['<ruby>私<rt>わたし</rt></ruby>の<ruby>町<rt>まち</rt></ruby>',"___",'<ruby>日本人<rt>にほんじん</rt></ruby>',"___",'います。'], ans:["に","が"], hint:"Lebewesen → います"},
]},
/* ---------- CM_7-3 noun1 は noun2 が adj です ---------- */
{id:'cm7-3', code:'CM_7-3', title:'noun1 は noun2 が adj です',
grammar:'<b>{Nomen1 は}{Nomen2 が}{Adjektiv です}</b> — etwas anhand eines Merkmals beschreiben (Ort/Können/Eigenschaft).',
vocab:[
{jpr:'おいしい', read:"おいしい", de:"lecker", en:"delicious", kana:"おいしい"},
{jpr:'<ruby>有名<rt>ゆうめい</rt></ruby>', read:"ゆうめい", de:"berühmt", en:"famous", kana:"ゆうめい"},
{jpr:'お<ruby>寺<rt>てら</rt></ruby>', read:"おてら", de:"Tempel", en:"temple", kana:"おてら"},
{jpr:'<ruby>上手<rt>じょうず</rt></ruby>', read:"じょうず", de:"gut können", en:"good at", kana:"じょうず"},
{jpr:'<ruby>友達<rt>ともだち</rt></ruby>', read:"ともだち", de:"Freund", en:"friend", kana:"ともだち"},
{jpr:'<ruby>日本語<rt>にほんご</rt></ruby>', read:"にほんご", de:"Japanisch", en:"Japanese (language)", kana:"にほんご"},
{jpr:'みそラーメン', read:"みそらーめん", de:"Miso-Ramen", en:"miso ramen", kana:"みそらーめん"},
{jpr:'<ruby>船<rt>ふね</rt></ruby>', read:"ふね", de:"Schiff", en:"ship", kana:"ふね"},
{jpr:'<ruby>妹<rt>いもうと</rt></ruby>', read:"いもうと", de:"jüngere Schwester", en:"younger sister", kana:"いもうと"},
{jpr:'ゲーム', read:"げーむ", de:"Spiel", en:"game", kana:"げーむ"},
],
verbs:[],
sentences:[
{de:"Bei Ippudo ist der Miso-Ramen lecker.", en:"As for Ippudo, its miso ramen is delicious.", r:'<ruby>一風堂<rt>いっぷうどう</rt></ruby><span class="p-wa">は</span> みそラーメン<span class="p-ga">が</span> おいしいです。', read:"いっぷうどうは みそらーめんが おいしいです。"},
{de:"Bei Coco Ichi ist das Curry lecker.", en:"As for CoCo Ichi, its curry is delicious.", r:'ココイチ<span class="p-wa">は</span> カレー<span class="p-ga">が</span> おいしいです。', read:"ここいちは かれーが おいしいです。"},
{de:"Kyoto ist berühmt für seine Tempel.", en:"As for Kyoto, its temples are famous.", r:'<ruby>京都<rt>きょうと</rt></ruby><span class="p-wa">は</span> お<ruby>寺<rt>てら</rt></ruby><span class="p-ga">が</span> <ruby>有名<rt>ゆうめい</rt></ruby>です。', read:"きょうとは おてらが ゆうめいです。"},
{de:"Flensburg ist berühmt für seine Schiffe.", en:"As for Flensburg, its ships are famous.", r:'フレンスブルク<span class="p-wa">は</span> <ruby>船<rt>ふね</rt></ruby><span class="p-ga">が</span> <ruby>有名<rt>ゆうめい</rt></ruby>です。', read:"ふれんすぶるくは ふねが ゆうめいです。"},
{de:"Mein Freund ist gut in Japanisch.", en:"As for my friend, they're good at Japanese.", r:'<ruby>私<rt>わたし</rt></ruby>の<ruby>友達<rt>ともだち</rt></ruby><span class="p-wa">は</span> <ruby>日本語<rt>にほんご</rt></ruby><span class="p-ga">が</span> <ruby>上手<rt>じょうず</rt></ruby>です。', read:"わたしのともだちは にほんごが じょうずです。"},
{de:"Meine Schwester ist gut in Videospielen.", en:"My sister is good at games.", r:'<ruby>私<rt>わたし</rt></ruby>の<ruby>妹<rt>いもうと</rt></ruby><span class="p-wa">は</span> ゲーム<span class="p-ga">が</span> <ruby>上手<rt>じょうず</rt></ruby>です。', read:"わたしのいもうとは げーむが じょうずです。"},
],
adjectives:[
{jpr:'おいしい', read:"おいしい", de:"lecker", type:'i', negr:'おいしくない', negKana:"おいしくない", rule:"い-Adj: い weg → くない"},
{jpr:'<ruby>有名<rt>ゆうめい</rt></ruby>', read:"ゆうめい", de:"berühmt", type:'na', negr:'<ruby>有名<rt>ゆうめい</rt></ruby>じゃない', negKana:"ゆうめいじゃない", rule:"な-Adj: + じゃない (kein くない!)"},
{jpr:'<ruby>上手<rt>じょうず</rt></ruby>', read:"じょうず", de:"gut können", type:'na', negr:'<ruby>上手<rt>じょうず</rt></ruby>じゃない', negKana:"じょうずじゃない", rule:"な-Adj: + じゃない"},
],
particles:[
{parts:['<ruby>一風堂<rt>いっぷうどう</rt></ruby>',"___",'みそラーメン',"___",'おいしいです。'], ans:["は","が"], hint:"Thema は … Merkmal が"},
{parts:['<ruby>京都<rt>きょうと</rt></ruby>',"___",'お<ruby>寺<rt>てら</rt></ruby>',"___",'<ruby>有名<rt>ゆうめい</rt></ruby>です。'], ans:["は","が"], hint:"Thema は … Merkmal が"},
{parts:['<ruby>友達<rt>ともだち</rt></ruby>',"___",'<ruby>日本語<rt>にほんご</rt></ruby>',"___",'<ruby>上手<rt>じょうず</rt></ruby>です。'], ans:["は","が"], hint:"bei 上手 steht が"},
]},
/* ---------- CM_7-5 The Purpose of Movement (bestehend IDs unverändert) ---------- */
{id:'cm7-5', code:'CM_7-5', title:'The Purpose of Movement',
grammar:'<b>{Ziel に}{Nomen を}{V ますStamm に}{いきます}</b> — irgendwohin gehen, <b>um</b> etwas zu tun. Gegensatz: <b>~で</b> = Ort einer Handlung.',
vocab:VOCAB, verbs:VERBS, sentences:SENTENCES, particles:PARTICLES},
/* ---------- CM_11-3 ~ことがあります ---------- */
{id:'cm11-3', code:'CM_11-3', title:'~ことがあります (Erfahrung)',
grammar:'<b>{V た-Form}{ことが}{あります}</b> — „schon mal … getan haben". <b>こと</b> macht aus dem Verb ein Nomen; た-Form nötig (いく→いった).',
vocab:[
{jpr:'こと', read:"こと", de:"(Nominalisierer)", en:"noun-maker", kana:"こと"},
{jpr:'<ruby>北海道<rt>ほっかいどう</rt></ruby>', read:"ほっかいどう", de:"Hokkaido", en:"Hokkaido", kana:"ほっかいどう"},
{jpr:'そば', read:"そば", de:"Soba(-Nudeln)", en:"soba", kana:"そば"},
{jpr:'<ruby>金沢<rt>かなざわ</rt></ruby>', read:"かなざわ", de:"Kanazawa", en:"Kanazawa", kana:"かなざわ"},
{jpr:'<ruby>行<rt>い</rt></ruby>った', read:"いった", de:"gegangen (た-Form)", en:"went", kana:"いった"},
{jpr:'<ruby>食<rt>た</rt></ruby>べた', read:"たべた", de:"gegessen (た-Form)", en:"ate", kana:"たべた"},
{jpr:'デンマーク', read:"でんまーく", de:"Dänemark", en:"Denmark", kana:"でんまーく"},
],
verbs:[],
sentences:[
{de:"Ich war schon mal in Japan.", en:"I have been to Japan.", r:'<ruby>日本<rt>にほん</rt></ruby><span class="p-ni">に</span> <ruby>行<rt>い</rt></ruby>った こと<span class="p-ga">が</span> あります。', read:"にほんに いった ことが あります。"},
{de:"Ich war schon mal in Osaka.", en:"I have been to Osaka.", r:'<ruby>大阪<rt>おおさか</rt></ruby><span class="p-ni">に</span> <ruby>行<rt>い</rt></ruby>った こと<span class="p-ga">が</span> あります。', read:"おおさかに いった ことが あります。"},
{de:"Warst du schon mal in Hokkaido? — Nein, noch nie.", en:"Have you been to Hokkaido? — No, I haven't.", r:'<ruby>北海道<rt>ほっかいどう</rt></ruby><span class="p-ni">に</span> <ruby>行<rt>い</rt></ruby>った こと<span class="p-ga">が</span> ありますか。いえ。ありません。', read:"ほっかいどうに いった ことが ありますか。いえ。ありません。"},
{de:"Ich habe schon mal Ramen gegessen.", en:"I have eaten ramen.", r:'ラーメン<span class="p-wo">を</span> <ruby>食<rt>た</rt></ruby>べた こと<span class="p-ga">が</span> あります。', read:"らーめんを たべた ことが あります。"},
{de:"Wo hast du es gegessen? — In Kanazawa.", en:"Where did you eat it? — In Kanazawa.", r:'どこ<span class="p-de">で</span> <ruby>食<rt>た</rt></ruby>べましたか。かなざわ<span class="p-de">で</span> <ruby>食<rt>た</rt></ruby>べました。', read:"どこで たべましたか。かなざわで たべました。"},
],
particles:[
{parts:['<ruby>日本<rt>にほん</rt></ruby>',"___",'<ruby>行<rt>い</rt></ruby>った こと',"___",'あります。'], ans:["に","が"], hint:"Ziel に … こと が"},
{parts:['ラーメン',"___",'<ruby>食<rt>た</rt></ruby>べた こと',"___",'あります。'], ans:["を","が"], hint:"Objekt を … こと が"},
{parts:['どこ',"___",'<ruby>食<rt>た</rt></ruby>べましたか。'], ans:["で"], hint:"Ort der Handlung"},
]},
/* ---------- CM_20-5 Name という Item ---------- */
{id:'cm20-5', code:'CM_20-5', title:'Name という Item',
grammar:'<b>{Nomen}{という}{Nomen2}</b> — „ein …(Nomen2) <b>namens</b> …(Nomen)".',
vocab:[
{jpr:'という', read:"という", de:"genannt / namens", en:"called, named", kana:"という"},
{jpr:'<ruby>一風堂<rt>いっぷうどう</rt></ruby>', read:"いっぷうどう", de:"Ippudo (Ramen-Kette)", en:"Ippudo", kana:"いっぷうどう"},
{jpr:'カレー<ruby>屋<rt>や</rt></ruby>', read:"かれーや", de:"Curry-Laden", en:"curry shop", kana:"かれーや"},
{jpr:'たこ<ruby>焼<rt>や</rt></ruby>き', read:"たこやき", de:"Takoyaki", en:"takoyaki", kana:"たこやき"},
{jpr:'ラーメン<ruby>屋<rt>や</rt></ruby>', read:"らーめんや", de:"Ramen-Laden", en:"ramen shop", kana:"らーめんや"},
],
verbs:[],
sentences:[
{de:"Ich war in einem Ramen-Laden namens Ippudo.", en:"I went to a ramen shop called Ippudo.", r:'<ruby>一風堂<rt>いっぷうどう</rt></ruby>という ラーメン<ruby>屋<rt>や</rt></ruby><span class="p-ni">に</span> <ruby>行<rt>い</rt></ruby>きました。', read:"いっぷうどうという らーめんやに いきました。"},
{de:"Ich war in einem Curry-Laden namens Cocos Curry.", en:"I went to a curry shop called Cocos Curry.", r:'ココスカレーという カレー<ruby>屋<rt>や</rt></ruby><span class="p-ni">に</span> <ruby>行<rt>い</rt></ruby>きました。', read:"ここすかれーという かれーやに いきました。"},
{de:"Ich habe ein Gericht namens Takoyaki gegessen.", en:"I ate a food called takoyaki.", r:'たこ<ruby>焼<rt>や</rt></ruby>きという <ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby><span class="p-wo">を</span> <ruby>食<rt>た</rt></ruby>べました。', read:"たこやきという たべものを たべました。"},
],
particles:[
{parts:['<ruby>一風堂<rt>いっぷうどう</rt></ruby>という ラーメン<ruby>屋<rt>や</rt></ruby>',"___",'<ruby>行<rt>い</rt></ruby>きました。'], ans:["に"], hint:"Bewegungsziel"},
{parts:['たこ<ruby>焼<rt>や</rt></ruby>きという <ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby>',"___",'<ruby>食<rt>た</rt></ruby>べました。'], ans:["を"], hint:"Objekt"},
]},
/* ---------- SP_Degree Adverb (crazy) めっちゃ ---------- */
{id:'sp-meccha', code:'SP_めっちゃ', title:'Degree Adverb (crazy)',
grammar:'<b>{Nomen は}{めっちゃ}{Adjektiv です}</b> — めっちゃ = „extrem/voll" (locker, gesprochen; stärker/emotionaler als とても).',
vocab:[
{jpr:'めっちゃ', read:"めっちゃ", de:"extrem / voll (locker)", en:"extremely (casual)", kana:"めっちゃ"},
{jpr:'<ruby>甘<rt>あま</rt></ruby>い', read:"あまい", de:"süß", en:"sweet", kana:"あまい"},
{jpr:'アイスクリーム', read:"あいすくりーむ", de:"Eis", en:"ice cream", kana:"あいすくりーむ"},
{jpr:'いちご', read:"いちご", de:"Erdbeere", en:"strawberry", kana:"いちご"},
{jpr:'とても', read:"とても", de:"sehr (neutral)", en:"very", kana:"とても"},
],
verbs:[],
sentences:[
{de:"Nakamoto ist extrem scharf!", en:"Nakamoto is crazy spicy!", r:'<ruby>仲本<rt>なかもと</rt></ruby><span class="p-wa">は</span> めっちゃ からいです!', read:"なかもとは めっちゃ からいです!"},
{de:"Erdbeer-Eis ist extrem süß!", en:"Strawberry ice cream is crazy sweet!", r:'いちごの アイスクリーム<span class="p-wa">は</span> めっちゃ <ruby>甘<rt>あま</rt></ruby>いです!', read:"いちごの あいすくりーむは めっちゃ あまいです!"},
],
adjectives:[
{jpr:'<ruby>甘<rt>あま</rt></ruby>い', read:"あまい", de:"süß", type:'i', negr:'<ruby>甘<rt>あま</rt></ruby>くない', negKana:"あまくない", rule:"い-Adj: い weg → くない"},
],
particles:[
{parts:['<ruby>仲本<rt>なかもと</rt></ruby>',"___",'めっちゃ からいです。'], ans:["は"], hint:"Themenpartikel"},
]},
/* ---------- SP_Degree Adverb (fairly) まあまあ ---------- */
{id:'sp-maamaa', code:'SP_まあまあ', title:'Degree Adverb (fairly)',
grammar:'<b>{Nomen は}{まあまあ}{Adjektiv です}</b> — „einigermaßen/mittelmäßig". <b>まあまあ</b> allein = „geht so". Bescheiden auf Lob: <b>まだまだです</b>.',
vocab:[
{jpr:'まあまあ', read:"まあまあ", de:"einigermaßen / geht so", en:"fairly, so-so", kana:"まあまあ"},
{jpr:'おもしろい', read:"おもしろい", de:"interessant", en:"interesting", kana:"おもしろい"},
{jpr:'アニメ', read:"あにめ", de:"Anime", en:"anime", kana:"あにめ"},
{jpr:'レストラン', read:"れすとらん", de:"Restaurant", en:"restaurant", kana:"れすとらん"},
{jpr:'まだまだです', read:"まだまだです", de:"noch ein weiter Weg (bescheiden)", en:"I still have a long way to go", kana:"まだまだです"},
],
verbs:[],
sentences:[
{de:"Dieser Ramen ist einigermaßen scharf.", en:"This ramen is fairly spicy.", r:'このラーメン<span class="p-wa">は</span> まあまあ からいです。', read:"このらーめんは まあまあ からいです。"},
{de:"Dieser Anime ist einigermaßen interessant.", en:"This anime is fairly interesting.", r:'このアニメ<span class="p-wa">は</span> まあまあ おもしろいです。', read:"このあにめは まあまあ おもしろいです。"},
{de:"Dieser Anime ist okay.", en:"This anime is okay.", r:'このアニメ<span class="p-wa">は</span> まあまあです。', read:"このあにめは まあまあです。"},
{de:"Dieses Restaurant ist okay.", en:"This restaurant is okay.", r:'このレストラン<span class="p-wa">は</span> まあまあです。', read:"このれすとらんは まあまあです。"},
{de:"Bescheidene Antwort auf Lob (Ach, noch lange nicht.').", en:"Response to a compliment: I still have a long way to go.", r:'まだまだです。', read:"まだまだです。"},
],
adjectives:[
{jpr:'おもしろい', read:"おもしろい", de:"interessant", type:'i', negr:'おもしろくない', negKana:"おもしろくない", rule:"い-Adj: い weg → くない"},
],
particles:[
{parts:['このラーメン',"___",'まあまあ からいです。'], ans:["は"], hint:"Themenpartikel"},
{parts:['このアニメ',"___",'まあまあです。'], ans:["は"], hint:"Themenpartikel"},
]},
/* ---------- Verbgruppen (ますStamm) ---------- */
{id:'verbs', code:'Verben', title:'Verbgruppen & ます',
grammar:'3 Gruppen: ① <b>Ru-Verben</b> (る weg) ② <b>U-Verben</b> (u→i) ③ <b>unregelmäßig</b> (する→し, くる→き). Hier: höfliche ます-Form.',
vocab:[
{jpr:'<ruby>寝<rt>ね</rt></ruby>る', read:"ねる(ねます)", de:"schlafen", en:"to sleep", kana:"ねる"},
{jpr:'<ruby>起<rt>お</rt></ruby>きる', read:"おきる(おきます)", de:"aufstehen", en:"to get up", kana:"おきる"},
{jpr:'<ruby>読<rt>よ</rt></ruby>む', read:"よむ(よみます)", de:"lesen", en:"to read", kana:"よむ"},
{jpr:'<ruby>聞<rt>き</rt></ruby>く', read:"きく(ききます)", de:"hören / zuhören", en:"to listen", kana:"きく"},
{jpr:'<ruby>来<rt>く</rt></ruby>る', read:"くる(きます)", de:"kommen", en:"to come", kana:"くる"},
{jpr:'<ruby>勉強<rt>べんきょう</rt></ruby>する', read:"べんきょうする", de:"lernen / studieren", en:"to study", kana:"べんきょうする"},
],
verbs:[
{jpr:'<ruby>食<rt>た</rt></ruby>べる', de:"essen", group:"Gruppe 2 (ru-Verb)", stemr:'<ruby>食<rt>た</rt></ruby>べ', stemKana:"たべ", masur:'<ruby>食<rt>た</rt></ruby>べます', rule:"ru-Verb: る weg → たべ"},
{jpr:'<ruby>寝<rt>ね</rt></ruby>る', de:"schlafen", group:"Gruppe 2 (ru-Verb)", stemr:'<ruby>寝<rt>ね</rt></ruby>', stemKana:"ね", masur:'<ruby>寝<rt>ね</rt></ruby>ます', rule:"ru-Verb: る weg → ね"},
{jpr:'<ruby>見<rt>み</rt></ruby>る', de:"sehen", group:"Gruppe 2 (ru-Verb)", stemr:'<ruby>見<rt>み</rt></ruby>', stemKana:"み", masur:'<ruby>見<rt>み</rt></ruby>ます', rule:"ru-Verb: る weg → み"},
{jpr:'<ruby>起<rt>お</rt></ruby>きる', de:"aufstehen", group:"Gruppe 2 (ru-Verb)", stemr:'<ruby>起<rt>お</rt></ruby>き', stemKana:"おき", masur:'<ruby>起<rt>お</rt></ruby>きます', rule:"ru-Verb: る weg → おき"},
{jpr:'<ruby>飲<rt>の</rt></ruby>む', de:"trinken", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>飲<rt>の</rt></ruby>み', stemKana:"のみ", masur:'<ruby>飲<rt>の</rt></ruby>みます', rule:"u-Verb: む → み"},
{jpr:'<ruby>読<rt>よ</rt></ruby>む', de:"lesen", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>読<rt>よ</rt></ruby>み', stemKana:"よみ", masur:'<ruby>読<rt>よ</rt></ruby>みます', rule:"u-Verb: む → み"},
{jpr:'<ruby>話<rt>はな</rt></ruby>す', de:"sprechen", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>話<rt>はな</rt></ruby>し', stemKana:"はなし", masur:'<ruby>話<rt>はな</rt></ruby>します', rule:"u-Verb: す → し"},
{jpr:'<ruby>聞<rt>き</rt></ruby>く', de:"hören", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>聞<rt>き</rt></ruby>き', stemKana:"きき", masur:'<ruby>聞<rt>き</rt></ruby>きます', rule:"u-Verb: く → き"},
{jpr:'<ruby>行<rt>い</rt></ruby>く', de:"gehen", group:"Gruppe 1 (u-Verb)", stemr:'<ruby>行<rt>い</rt></ruby>き', stemKana:"いき", masur:'<ruby>行<rt>い</rt></ruby>きます', rule:"u-Verb: く → き"},
{jpr:'<ruby>帰<rt>かえ</rt></ruby>る', de:"heimgehen", group:"Gruppe 1 (Ausnahme!)", stemr:'<ruby>帰<rt>かえ</rt></ruby>り', stemKana:"かえり", masur:'<ruby>帰<rt>かえ</rt></ruby>ります', rule:"sieht aus wie ru-Verb, ist u-Verb: る → り"},
{jpr:'する', de:"machen / tun", group:"Gruppe 3 (unregelmäßig)", stemr:'し', stemKana:"し", masur:'します', rule:"unregelmäßig: する → し"},
{jpr:'<ruby>勉強<rt>べんきょう</rt></ruby>する', de:"lernen", group:"Gruppe 3 (unregelmäßig)", stemr:'<ruby>勉強<rt>べんきょう</rt></ruby>し', stemKana:"べんきょうし", masur:'<ruby>勉強<rt>べんきょう</rt></ruby>します', rule:"する-Verb: する → し"},
{jpr:'<ruby>来<rt>く</rt></ruby>る', de:"kommen", group:"Gruppe 3 (unregelmäßig)", stemr:'<ruby>来<rt>き</rt></ruby>', stemKana:"き", masur:'<ruby>来<rt>き</rt></ruby>ます', rule:"unregelmäßig: くる → き"},
],
sentences:[
{de:"Ich esse Sushi. (höflich)", en:"I eat sushi.", r:'すし<span class="p-wo">を</span> <ruby>食<rt>た</rt></ruby>べます。', read:"すしを たべます。"},
{de:"Ich sehe einen Anime. (höflich)", en:"I watch anime.", r:'アニメ<span class="p-wo">を</span> <ruby>見<rt>み</rt></ruby>ます。', read:"あにめを みます。"},
{de:"Ich spiele ein Spiel. (höflich)", en:"I play a game.", r:'ゲーム<span class="p-wo">を</span> します。', read:"げーむを します。"},
{de:"Mein Freund kommt nach Japan.", en:"My friend comes to Japan.", r:'<ruby>友達<rt>ともだち</rt></ruby><span class="p-ga">が</span> <ruby>日本<rt>にほん</rt></ruby><span class="p-ni">に</span> <ruby>来<rt>き</rt></ruby>ます。', read:"ともだちが にほんに きます。"},
],
particles:[
{parts:['すし',"___",'<ruby>食<rt>た</rt></ruby>べます。'], ans:["を"], hint:"Objekt"},
{parts:['ゲーム',"___",'します。'], ans:["を"], hint:"Objekt"},
{parts:['<ruby>友達<rt>ともだち</rt></ruby>',"___",'<ruby>日本<rt>にほん</rt></ruby>',"___",'<ruby>来<rt>き</rt></ruby>ます。'], ans:["が","に"], hint:"Subjekt が … Ziel に"},
]},
/* ---------- て-Form ---------- */
{id:'teform', code:'て-Form', title:'te-form conjugations',
grammar:'<b>Ru</b>→て · <b>う/つ/る</b>→って · <b>む/ぶ/ぬ</b>→んで · <b>く</b>→いて (<b>行く→行って</b>!) · <b>ぐ</b>→いで · <b>す</b>→して · する→して, くる→きて.',
vocab:[
{jpr:'<ruby>会<rt>あ</rt></ruby>う', read:"あう", de:"(sich) treffen", en:"to meet", kana:"あう"},
{jpr:'<ruby>待<rt>ま</rt></ruby>つ', read:"まつ", de:"warten", en:"to wait", kana:"まつ"},
{jpr:'<ruby>遊<rt>あそ</rt></ruby>ぶ', read:"あそぶ", de:"spielen / sich vergnügen", en:"to play", kana:"あそぶ"},
{jpr:'<ruby>泳<rt>およ</rt></ruby>ぐ', read:"およぐ", de:"schwimmen", en:"to swim", kana:"およぐ"},
{jpr:'<ruby>書<rt>か</rt></ruby>く', read:"かく", de:"schreiben", en:"to write", kana:"かく"},
],
verbs:[],
sentences:[
{de:"て-Form von 食べる (essen)? — Ru-Verb: る→て", en:"", r:'<ruby>食<rt>た</rt></ruby>べて', read:"たべて"},
{de:"て-Form von 見る (sehen)? — Ru-Verb: る→て", en:"", r:'<ruby>見<rt>み</rt></ruby>て', read:"みて"},
{de:"て-Form von 会う (treffen)? — う→って", en:"", r:'<ruby>会<rt>あ</rt></ruby>って', read:"あって"},
{de:"て-Form von 待つ (warten)? — つ→って", en:"", r:'<ruby>待<rt>ま</rt></ruby>って', read:"まって"},
{de:"て-Form von 帰る (heimgehen)? — る→って", en:"", r:'<ruby>帰<rt>かえ</rt></ruby>って', read:"かえって"},
{de:"て-Form von 読む (lesen)? — む→んで", en:"", r:'<ruby>読<rt>よ</rt></ruby>んで', read:"よんで"},
{de:"て-Form von 遊ぶ (spielen)? — ぶ→んで", en:"", r:'<ruby>遊<rt>あそ</rt></ruby>んで', read:"あそんで"},
{de:"て-Form von 書く (schreiben)? — く→いて", en:"", r:'<ruby>書<rt>か</rt></ruby>いて', read:"かいて"},
{de:"て-Form von 行く (gehen)? — AUSNAHME: →行って", en:"", r:'<ruby>行<rt>い</rt></ruby>って', read:"いって"},
{de:"て-Form von 泳ぐ (schwimmen)? — ぐ→いで", en:"", r:'<ruby>泳<rt>およ</rt></ruby>いで', read:"およいで"},
{de:"て-Form von 話す (sprechen)? — す→して", en:"", r:'<ruby>話<rt>はな</rt></ruby>して', read:"はなして"},
{de:"て-Form von する (machen)? — unregelmäßig", en:"", r:'して', read:"して"},
{de:"て-Form von 来る (kommen)? — unregelmäßig", en:"", r:'<ruby>来<rt>き</rt></ruby>て', read:"きて"},
],
particles:[]},
/* ---------- CM_5-1 Adjectives Present Tense ---------- */
{id:'cm5-1', code:'CM_5-1', title:'Adjectives Present Tense',
grammar:'<b>い-Adj:</b> {Nomen は}{…いです}, verneint {…<b>くない</b>です} (からい→から<b>くない</b>). Ausnahme <b>いい→よくない</b>. <b>な-Adj:</b> {…です}, verneint {…<b>じゃない</b>です}. Achtung: <b>きれい・ゆうめい</b> sehen aus wie い-Adj, sind aber な-Adj! Grad: <b>とても</b>/<b>ちょっと</b>/<b>あんまり</b> + Adj.',
vocab:[
{jpr:'からい', read:"からい", de:"scharf", en:"spicy", kana:"からい"},
{jpr:'あたらしい', read:"あたらしい", de:"neu", en:"new", kana:"あたらしい"},
{jpr:'いい', read:"いい", de:"gut", en:"good", kana:"いい"},
{jpr:'あたたかい', read:"あたたかい", de:"warm", en:"warm", kana:"あたたかい"},
{jpr:'さむい', read:"さむい", de:"kalt", en:"cold", kana:"さむい"},
{jpr:'きれい', read:"きれい", de:"schön / sauber", en:"beautiful, clean", kana:"きれい"},
{jpr:'<ruby>有名<rt>ゆうめい</rt></ruby>', read:"ゆうめい", de:"berühmt", en:"famous", kana:"ゆうめい"},
{jpr:'<ruby>人気<rt>にんき</rt></ruby>', read:"にんき", de:"beliebt", en:"popular", kana:"にんき"},
{jpr:'<ruby>簡単<rt>かんたん</rt></ruby>', read:"かんたん", de:"einfach", en:"easy", kana:"かんたん"},
{jpr:'パソコン', read:"ぱそこん", de:"Computer / Laptop", en:"computer", kana:"ぱそこん"},
{jpr:'とても', read:"とても", de:"sehr", en:"very", kana:"とても"},
{jpr:'ちょっと', read:"ちょっと", de:"ein bisschen", en:"a little", kana:"ちょっと"},
],
verbs:[],
adjectives:[
{jpr:'からい', read:"からい", de:"scharf", type:'i', negr:'からくない', negKana:"からくない", rule:"い-Adj: い weg → くない"},
{jpr:'あたらしい', read:"あたらしい", de:"neu", type:'i', negr:'あたらしくない', negKana:"あたらしくない", rule:"い-Adj: い weg → くない"},
{jpr:'あたたかい', read:"あたたかい", de:"warm", type:'i', negr:'あたたかくない', negKana:"あたたかくない", rule:"い-Adj: い weg → くない"},
{jpr:'さむい', read:"さむい", de:"kalt", type:'i', negr:'さむくない', negKana:"さむくない", rule:"い-Adj: い weg → くない"},
{jpr:'いい', read:"いい", de:"gut", type:'i-exc', negr:'よくない', negKana:"よくない", rule:"⚠ Ausnahme: いい → よくない (nicht いくない!)"},
{jpr:'きれい', read:"きれい", de:"schön / sauber", type:'na', negr:'きれいじゃない', negKana:"きれいじゃない", rule:"な-Adj: + じゃない (kein くない!)"},
{jpr:'<ruby>有名<rt>ゆうめい</rt></ruby>', read:"ゆうめい", de:"berühmt", type:'na', negr:'<ruby>有名<rt>ゆうめい</rt></ruby>じゃない', negKana:"ゆうめいじゃない", rule:"な-Adj (sieht aus wie い-Adj!): + じゃない"},
{jpr:'<ruby>人気<rt>にんき</rt></ruby>', read:"にんき", de:"beliebt", type:'na', negr:'<ruby>人気<rt>にんき</rt></ruby>じゃない', negKana:"にんきじゃない", rule:"な-Adj: + じゃない"},
{jpr:'<ruby>簡単<rt>かんたん</rt></ruby>', read:"かんたん", de:"einfach", type:'na', negr:'<ruby>簡単<rt>かんたん</rt></ruby>じゃない', negKana:"かんたんじゃない", rule:"な-Adj: + じゃない"},
],
sentences:[
{de:"Dieser Ramen ist scharf.", en:"This ramen is spicy.", r:'このラーメン<span class="p-wa">は</span> からいです。', read:"このらーめんは からいです。"},
{de:"Dieser Ramen ist nicht scharf.", en:"This ramen is not spicy.", r:'このラーメン<span class="p-wa">は</span> からくないです。', read:"このらーめんは からくないです。"},
{de:"Dieses Sushi-Restaurant ist neu.", en:"This sushi restaurant is new.", r:'この おすしや<span class="p-wa">は</span> あたらしいです。', read:"この おすしやは あたらしいです。"},
{de:"Dieser Computer ist gut.", en:"This computer is good.", r:'このパソコン<span class="p-wa">は</span> いいです。', read:"このぱそこんは いいです。"},
{de:"Dieser Computer ist nicht gut. (Ausnahme いい→よくない!)", en:"This computer is not good.", r:'このパソコン<span class="p-wa">は</span> よくないです。', read:"このぱそこんは よくないです。"},
{de:"Diese Stadt ist schön.", en:"This city is beautiful.", r:'この<ruby>町<rt>まち</rt></ruby><span class="p-wa">は</span> きれいです。', read:"このまちは きれいです。"},
{de:"Diese Stadt ist nicht schön. (な-Adj → じゃない)", en:"This city is not beautiful.", r:'この<ruby>町<rt>まち</rt></ruby><span class="p-wa">は</span> きれいじゃないです。', read:"このまちは きれいじゃないです。"},
{de:"Japanisches Essen ist beliebt.", en:"Japanese food is popular.", r:'<ruby>日本<rt>にほん</rt></ruby>の<ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby><span class="p-wa">は</span> <ruby>人気<rt>にんき</rt></ruby>です。', read:"にほんのたべものは にんきです。"},
{de:"Dieses Buch ist einfach.", en:"This book is easy.", r:'この<ruby>本<rt>ほん</rt></ruby><span class="p-wa">は</span> <ruby>簡単<rt>かんたん</rt></ruby>です。', read:"このほんは かんたんです。"},
{de:"Dieses Buch ist nicht einfach.", en:"This book is not easy.", r:'この<ruby>本<rt>ほん</rt></ruby><span class="p-wa">は</span> <ruby>簡単<rt>かんたん</rt></ruby>じゃないです。', read:"このほんは かんたんじゃないです。"},
{de:"Dieser Ramen ist sehr scharf.", en:"This ramen is very spicy.", r:'このラーメン<span class="p-wa">は</span> とても からいです。', read:"このらーめんは とても からいです。"},
{de:"Dieser Ramen ist ein bisschen scharf.", en:"This ramen is a little spicy.", r:'このラーメン<span class="p-wa">は</span> ちょっと からいです。', read:"このらーめんは ちょっと からいです。"},
{de:"Dieser Ramen ist nicht sehr scharf.", en:"This ramen is not very spicy.", r:'このラーメン<span class="p-wa">は</span> あんまり からくないです。', read:"このらーめんは あんまり からくないです。"},
],
particles:[
{parts:['このラーメン',"___",'からいです。'], ans:["は"], hint:"Themenpartikel"},
{parts:['この<ruby>町<rt>まち</rt></ruby>',"___",'きれいじゃないです。'], ans:["は"], hint:"Themenpartikel"},
]},
/* ---------- CM_5-4 すきな (Lieblings-X) ---------- */
{id:'cm5-4', code:'CM_5-4', title:'すきな (My favorite X is Y)',
grammar:'<b>{(わたしの)すきな Nomen1 は}{Nomen2 です}</b> — „Mein Lieblings-…(N1) ist …(N2)". Frage: <b>{(…の)すきな Nomen は}{なんですか}</b>. <b>すき</b> ist ein な-Adj → attributiv <b>すきな</b>. Antwort mit <b>が</b>: Python<b>が</b>すきです · noch eins: Bash<b>も</b>すきです.',
vocab:[
{jpr:'<ruby>好<rt>す</rt></ruby>きな', read:"すきな", de:"Lieblings- / am liebsten", en:"favorite", kana:"すきな"},
{jpr:'<ruby>飲<rt>の</rt></ruby>み<ruby>物<rt>もの</rt></ruby>', read:"のみもの", de:"Getränk", en:"drink", kana:"のみもの"},
{jpr:'<ruby>音楽<rt>おんがく</rt></ruby>', read:"おんがく", de:"Musik", en:"music", kana:"おんがく"},
{jpr:'ドラマ', read:"どらま", de:"Serie / Drama", en:"drama", kana:"どらま"},
{jpr:'お<ruby>好<rt>この</rt></ruby>み<ruby>焼<rt>や</rt></ruby>き', read:"おこのみやき", de:"Okonomiyaki", en:"okonomiyaki", kana:"おこのみやき"},
{jpr:'グループ', read:"ぐるーぷ", de:"Gruppe / Band", en:"group", kana:"ぐるーぷ"},
{jpr:'<ruby>言語<rt>げんご</rt></ruby>', read:"げんご", de:"Sprache", en:"language", kana:"げんご"},
{jpr:'なん', read:"なん", de:"was", en:"what", kana:"なん"},
],
verbs:[],
sentences:[
{de:"Mein Lieblingsessen ist Ramen.", en:"My favorite food is ramen.", r:'<ruby>好<rt>す</rt></ruby>きな <ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby><span class="p-wa">は</span> ラーメンです。', read:"すきな たべものは らーめんです。"},
{de:"Mein Lieblingsgetränk ist Kaffee.", en:"My favorite drink is coffee.", r:'<ruby>好<rt>す</rt></ruby>きな <ruby>飲<rt>の</rt></ruby>み<ruby>物<rt>もの</rt></ruby><span class="p-wa">は</span> コーヒーです。', read:"すきな のみものは こーひーです。"},
{de:"Mein Lieblingsessen ist Okonomiyaki.", en:"My favorite food is okonomiyaki.", r:'<ruby>好<rt>す</rt></ruby>きな <ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby><span class="p-wa">は</span> お<ruby>好<rt>この</rt></ruby>み<ruby>焼<rt>や</rt></ruby>きです。', read:"すきな たべものは おこのみやきです。"},
{de:"Was ist dein Lieblings-Anime?", en:"What is your favorite anime?", r:'Dさんの <ruby>好<rt>す</rt></ruby>きな アニメ<span class="p-wa">は</span> なんですか。', read:"Dさんの すきな あにめは なんですか。"},
{de:"Was ist deine Lieblingsmusik?", en:"What is your favorite music?", r:'<ruby>好<rt>す</rt></ruby>きな <ruby>音楽<rt>おんがく</rt></ruby><span class="p-wa">は</span> なんですか。', read:"すきな おんがくは なんですか。"},
{de:"Was ist deine Lieblings-Programmiersprache?", en:"What is your favorite programming language?", r:'<ruby>好<rt>す</rt></ruby>きな コンピューター<ruby>言語<rt>げんご</rt></ruby><span class="p-wa">は</span> なんですか。', read:"すきな こんぴゅーたーげんごは なんですか。"},
{de:"Ich mag Python.", en:"I like Python.", r:'Python<span class="p-ga">が</span> <ruby>好<rt>す</rt></ruby>きです。', read:"Pythonが すきです。"},
{de:"Bash mag ich auch.", en:"I like Bash too.", r:'Bash<span class="p-mo">も</span> <ruby>好<rt>す</rt></ruby>きです。', read:"Bashも すきです。"},
],
particles:[
{parts:['<ruby>好<rt>す</rt></ruby>きな <ruby>食<rt>た</rt></ruby>べ<ruby>物<rt>もの</rt></ruby>',"___",'ラーメンです。'], ans:["は"], hint:"Thema (Lieblings-X)"},
{parts:['Python',"___",'<ruby>好<rt>す</rt></ruby>きです。'], ans:["が"], hint:"bei 好き steht が"},
{parts:['Bash',"___",'<ruby>好<rt>す</rt></ruby>きです。'], ans:["も"], hint:"auch → も (noch eins dazu)"},
]},
/* ---------- CM_3-2 Question words 1 (なにを) ---------- */
{id:'cm3-2', code:'CM_3-2', title:'Question words 1 (なにを)',
grammar:'<b>{…はZeitangabe}{なに<span class="p-wo">を</span>}{V ますか}</b> — „Was machst du (wann)?". Antwort mit einem Verb: <b>…をします / …をたべます</b>. Das Objekt (auch das Fragewort なに) trägt <b>を</b>.',
vocab:[
{jpr:'なに', read:"なに", de:"was", en:"what", kana:"なに"},
{jpr:'<ruby>明日<rt>あした</rt></ruby>', read:"あした", de:"morgen", en:"tomorrow", kana:"あした"},
{jpr:'<ruby>週末<rt>しゅうまつ</rt></ruby>', read:"しゅうまつ", de:"Wochenende", en:"weekend", kana:"しゅうまつ"},
{jpr:'やきそば', read:"やきそば", de:"Yakisoba", en:"yakisoba", kana:"やきそば"},
{jpr:'カードゲーム', read:"かーどげーむ", de:"Kartenspiel", en:"card game", kana:"かーどげーむ"},
{jpr:'<ruby>休<rt>やす</rt></ruby>む', read:"やすむ(やすみます)", de:"sich ausruhen / freihaben", en:"to rest", kana:"やすむ"},
],
verbs:[],
sentences:[
{de:"Was machst du morgen?", en:"What will you do tomorrow?", r:'Dさん<span class="p-wa">は</span> <ruby>明日<rt>あした</rt></ruby> <ruby>何<rt>なに</rt></ruby><span class="p-wo">を</span> しますか。', read:"Dさんは あした なにを しますか。"},
{de:"Was machst du am Wochenende?", en:"What will you do on the weekend?", r:'<ruby>週末<rt>しゅうまつ</rt></ruby> <ruby>何<rt>なに</rt></ruby><span class="p-wo">を</span> しますか。', read:"しゅうまつ なにを しますか。"},
{de:"Ähm, ich ruhe mich aus.", en:"Um, I'll rest.", r:'ええと やすみます。', read:"ええと やすみます。"},
{de:"Ich spiele mit Freunden ein Kartenspiel.", en:"I'll play a card game with friends.", r:'<ruby>友達<rt>ともだち</rt></ruby>と カードゲーム<span class="p-wo">を</span> します。', read:"ともだちと かーどげーむを します。"},
{de:"Ich esse Yakisoba.", en:"I'll eat yakisoba.", r:'やきそば<span class="p-wo">を</span> <ruby>食<rt>た</rt></ruby>べます。', read:"やきそばを たべます。"},
],
particles:[
{parts:['<ruby>明日<rt>あした</rt></ruby> <ruby>何<rt>なに</rt></ruby>',"___",'しますか。'], ans:["を"], hint:"Fragewort なに als Objekt"},
{parts:['カードゲーム',"___",'します。'], ans:["を"], hint:"Objekt"},
]},
];
/* ================= RŌMAJI → KANA ================= */
const RMAP={a:'あ',i:'い',u:'う',e:'え',o:'お',
ka:'か',ki:'き',ku:'く',ke:'け',ko:'こ',kya:'きゃ',kyu:'きゅ',kyo:'きょ',
ga:'が',gi:'ぎ',gu:'ぐ',ge:'げ',go:'ご',gya:'ぎゃ',gyu:'ぎゅ',gyo:'ぎょ',
sa:'さ',shi:'し',si:'し',su:'す',se:'せ',so:'そ',sha:'しゃ',shu:'しゅ',sho:'しょ',sya:'しゃ',syu:'しゅ',syo:'しょ',
za:'ざ',ji:'じ',zi:'じ',zu:'ず',ze:'ぜ',zo:'ぞ',ja:'じゃ',ju:'じゅ',jo:'じょ',jya:'じゃ',jyu:'じゅ',jyo:'じょ',
ta:'た',chi:'ち',ti:'ち',tsu:'つ',tu:'つ',te:'て',to:'と',cha:'ちゃ',chu:'ちゅ',cho:'ちょ',tya:'ちゃ',tyu:'ちゅ',tyo:'ちょ',
da:'だ',di:'ぢ',du:'づ',de:'で',do:'ど',
na:'な',ni:'に',nu:'ぬ',ne:'ね',no:'の',nya:'にゃ',nyu:'にゅ',nyo:'にょ',
ha:'は',hi:'ひ',fu:'ふ',hu:'ふ',he:'へ',ho:'ほ',hya:'ひゃ',hyu:'ひゅ',hyo:'ひょ',
ba:'ば',bi:'び',bu:'ぶ',be:'べ',bo:'ぼ',bya:'びゃ',byu:'びゅ',byo:'びょ',
pa:'ぱ',pi:'ぴ',pu:'ぷ',pe:'ぺ',po:'ぽ',pya:'ぴゃ',pyu:'ぴゅ',pyo:'ぴょ',
ma:'ま',mi:'み',mu:'む',me:'め',mo:'も',mya:'みゃ',myu:'みゅ',myo:'みょ',
ya:'や',yu:'ゆ',yo:'よ',
ra:'ら',ri:'り',ru:'る',re:'れ',ro:'ろ',rya:'りゃ',ryu:'りゅ',ryo:'りょ',
wa:'わ',wo:'を',
fa:'ふぁ',fi:'ふぃ',fe:'ふぇ',fo:'ふぉ',
la:'ぁ',li:'ぃ',lu:'ぅ',le:'ぇ',lo:'ぉ',xa:'ぁ',xi:'ぃ',xu:'ぅ',xe:'ぇ',xo:'ぉ',
lya:'ゃ',lyu:'ゅ',lyo:'ょ',xya:'ゃ',xyu:'ゅ',xyo:'ょ',
ltu:'っ',xtu:'っ',ltsu:'っ',lwa:'ゎ',xwa:'ゎ',
'-':'ー'};
function toKana(s){
s=(s||'').toLowerCase().replace(/\s+/g,'');
let o='',i=0;
while(i<s.length){
const c=s[i];
if((c>='぀'&&c<='ヿ')||c==='ー'){o+=c;i++;continue;} // schon Kana
if(c==='t' && s[i+1]==='c' && s[i+2]==='h'){o+='っ';i++;continue;} // "tch" (matcha → まっちゃ)
if(c===s[i+1] && 'bcdfghjkmprstwyz'.includes(c)){o+='っ';i++;continue;} // Doppelkonsonant
if(c==='n' && s[i+1] && !'aiueoy'.includes(s[i+1])){o+='ん';i++;continue;}
if(c==='n' && !s[i+1]){o+='ん';i++;continue;}
let m=false;
for(let L=3;L>=1;L--){const ch=s.substr(i,L); if(RMAP[ch]){o+=RMAP[ch];i+=L;m=true;break;}}
if(!m){o+=c;i++;}
}
return o;
}
const norm = s => toKana(s)
.replace(/[・、。「」!?.,\s]/g,'') // Satzzeichen weg (ー bleibt!)
.replace(/[-ヺ]/g,ch=>String.fromCharCode(ch.charCodeAt(0)-96)); // Katakana → Hiragana, ー unberührt
// Streng: kleines ぇ ≠ großes え, ー muss getippt werden (mit "-"), っ muss stehen — alles wie im Original
/* ================= STATISTIK / PERSISTENZ ================= */
// Pro Karte: {box 0-5, right, wrong, last(Zeitstempel)}
let STATS = JSON.parse(localStorage.getItem('kody_stats')||'{}');
(function migrate(){
// 1) ganz alten Leitner-Stand (nur Zahlen) übernehmen
if(!Object.keys(STATS).length){
const old=JSON.parse(localStorage.getItem('kody_leitner')||'{}');
for(const k in old) STATS[k]={box:old[k]||0,right:0,wrong:0,last:0};
}
// 2) alte IDs ohne Lektions-Präfix der ersten Lektion zuordnen
let ch=false;
for(const k of Object.keys(STATS)){
if(/^(v|vb|s)\d+$/.test(k)){ STATS['cm7-5:'+k]=STATS[k]; delete STATS[k]; ch=true; }
}
if(ch||Object.keys(STATS).length) saveStats();
})();
function saveStats(){ localStorage.setItem('kody_stats',JSON.stringify(STATS)); }
function rec(id){ return STATS[id]||(STATS[id]={box:0,right:0,wrong:0,last:0}); }
const boxOf = id => (STATS[id]&&STATS[id].box)||0;
function bump(id,ok){
if(!id)return; const r=rec(id);
if(ok){ r.right++; r.box=Math.min(5,r.box+1); }
else { r.wrong++; r.box=0; } // was schlecht lief, kommt sofort wieder nach vorne
r.last=Date.now(); saveStats();
}
function boxesHtml(id){let h='<span class="boxes">';for(let k=0;k<5;k++)h+=`<i class="${k<boxOf(id)?'on':''}"></i>`;return h+'</span>';}
function isToday(ts){ if(!ts)return false; const d=new Date(ts),n=new Date();
return d.getFullYear()===n.getFullYear()&&d.getMonth()===n.getMonth()&&d.getDate()===n.getDate(); }
function doneToday(id){ const r=STATS[id]; return !!(r&&isToday(r.last)); }
// Metadaten der Karten (für Fortschritts-Seite) folgt der Lektionsauswahl
function allMeta(){
const o=[];
lessonsActive().forEach(L=>{
L.vocab.forEach((v,i)=>o.push({id:L.id+':v'+i, label:v.jpr+' · '+v.de, deck:'Vokabel'}));
L.verbs.forEach((v,i)=>o.push({id:L.id+':vb'+i, label:v.jpr+' → '+v.stemr, deck:'ますStamm'}));
(L.adjectives||[]).forEach((a,i)=>o.push({id:L.id+':a'+i, label:a.jpr+' → '+(a.negr||a.negKana), deck:'Adjektiv'}));
L.sentences.forEach((s,i)=>o.push({id:L.id+':s'+i, label:s.de, deck:'Satz'}));
});
PHRASES.forEach((p,i)=>o.push({id:'p'+i, label:p.jpr, deck:'Unterricht'}));
return o;
}
// Index über ALLE Lektionen (damit schwache Karten jeder Lektion gefunden werden)
function cardIndex(){
const m={};
const savedLesson=lesson; lesson='all';
[...vocabReview(),...verbItems(),...adjItems(),...sentenceItems(),...phraseItems()].forEach(it=>m[it.id]=it);
lesson=savedLesson;
return m;
}
function weakList(){ // geübte Karten, die noch wackeln schwächste zuerst
return allMeta().filter(m=>{const r=STATS[m.id]; return r&&(r.right+r.wrong>0)&&(r.wrong>0||r.box<4);})
.sort((a,b)=>{const ra=STATS[a.id],rb=STATS[b.id]; return (rb.wrong-ra.wrong)||(ra.box-rb.box);});
}
function weakDeck(){ const ci=cardIndex(); return weakList().map(m=>ci[m.id]).filter(Boolean); }
/* ================= DECK-BUILDER ================= */
function lessonsActive(){ return lesson==='all' ? LESSONS : LESSONS.filter(l=>l.id===lesson); }
function vocabItems(){
const out=[];
lessonsActive().forEach(L=>L.vocab.forEach((v,i)=>{ const id=L.id+':v'+i;
out.push(dir==='deJp'
? {id, front:`<div class="de">${v.de}</div><div class="en">${v.en}</div>`,
back:`<div class="jp">${v.jpr}</div><div class="reading">${v.read}</div>`, typeTarget:v.kana}
: {id, front:`<div class="jp">${v.jpr}</div>`,
back:`<div class="de">${v.de}</div><div class="reading">${v.read}</div>`, typeTarget:null});
}));
return out;
}
function vocabReview(){ // fürs Wiederholen immer DE→JP (Produktion)
const out=[];
lessonsActive().forEach(L=>L.vocab.forEach((v,i)=>out.push({id:L.id+':v'+i,
front:`<div class="de">${v.de}</div><div class="en">${v.en}</div>`,
back:`<div class="jp">${v.jpr}</div><div class="reading">${v.read}</div>`, typeTarget:v.kana})));
return out;
}
function verbItems(){
const out=[];
lessonsActive().forEach(L=>L.verbs.forEach((v,i)=>out.push({id:L.id+':vb'+i,
front:`<div class="jp">${v.jpr}</div><div class="en">${v.de} · ${v.group}</div><div class="q">ますStamm? (Form vor に / ます)</div>`,
back:`<div class="jp">${v.stemr}</div><div class="reading">→ ${v.masur}</div><div class="note">${v.rule}</div>`,
typeTarget:v.stemKana})));
return out;
}
function sentenceItems(){
const out=[];
lessonsActive().forEach(L=>L.sentences.forEach((s,i)=>out.push({id:L.id+':s'+i,
front:`<div class="de">${s.de}</div><div class="en">${s.en}</div>`,
back:`<div class="jp">${s.r}</div><div class="reading">${s.read}</div>`,
typeTarget:s.read.replace(/\s/g,'')})));
return out;
}
function particleItems(){
const out=[];
lessonsActive().forEach(L=>L.particles.forEach((p,i)=>out.push({...p, id:L.id+':pt'+i})));
return out;
}
function adjItems(){
const out=[];
lessonsActive().forEach(L=>(L.adjectives||[]).forEach((a,i)=>out.push({id:L.id+':a'+i,
front:`<div class="de">${a.de}</div><div class="jp">${a.jpr}</div><div class="q">verneinen → …ないです ${a.type==='na'?'(な-Adj)':a.type==='i-exc'?'(⚠ Ausnahme)':'(い-Adj)'}</div>`,
back:`<div class="jp">${a.negr||a.negKana}<span style="font-size:.6em"> です</span></div><div class="reading">${a.read} → ${a.negKana}です</div><div class="note">${a.rule}</div>`,
typeTarget:a.negKana})));
return out;
}
function phraseItems(){
return PHRASES.map((p,i)=>({id:'p'+i,
front:`<div class="de">${p.de}</div>`,
back:`<div class="jp">${p.jpr}</div><div class="reading">${p.read}</div>`,
typeTarget:p.read}));
}
function reviewDeck(){
const items=[...vocabReview(), ...verbItems(), ...adjItems(), ...phraseItems()];
return items.sort((a,b)=>boxOf(a.id)-boxOf(b.id)); // schwache zuerst
}
/* ================= STATE ================= */
let mode="review", queue=[], idx=0, correct=0, total=0, sessionAll=false;
let dir = localStorage.getItem('kody_dir')||'deJp';
let method = localStorage.getItem('kody_method')||'self'; // 'self' | 'type'
let lesson = localStorage.getItem('kody_lesson')||LESSONS[0].id; // Lektions-Filter oder 'all'
if(lesson!=='all' && !LESSONS.some(l=>l.id===lesson)) lesson=LESSONS[0].id;
const GENERIC=['review','weak','vocab','verbstem','sentence','phrases','adj'];
const app=document.getElementById("app");
const bar=document.getElementById("bar");
const counter=document.getElementById("counter");
const scoreEl=document.getElementById("score");
function shuffle(a){a=a.slice();for(let i=a.length-1;i>0;i--){const j=Math.random()*(i+1)|0;[a[i],a[j]]=[a[j],a[i]]}return a}
function deckFor(m){
if(m==="review") return reviewDeck();
if(m==="weak") return weakDeck();
if(m==="vocab") return shuffle(vocabItems());
if(m==="verbstem") return shuffle(verbItems());
if(m==="sentence") return shuffle(sentenceItems());
if(m==="phrases") return shuffle(phraseItems());
if(m==="particle") return shuffle(particleItems());
if(m==="adj") return shuffle(adjItems());
return [];
}
function start(m, all=false){
mode=m; idx=0; correct=0; total=0; sessionAll=all;
document.querySelectorAll("nav button").forEach(b=>b.classList.toggle("active",b.dataset.mode===m));
queue=deckFor(m);
// heute schon Erledigtes ausblenden aber NICHT im "schwache Karten"-Modus (der soll die heute verpatzten nochmal bringen)
if(!all && m!=='weak') queue=queue.filter(it=>!(it.id && doneToday(it.id)));
updateGrammarNote();
render();
}
function updateGrammarNote(){
const el=document.getElementById('grammarNote'); if(!el)return;
const ls=lessonsActive();
if(ls.length===1 && ls[0].grammar && ['review','vocab','verbstem','sentence','particle','adj'].includes(mode)){
el.style.display='block'; el.innerHTML='<b>'+ls[0].code+'</b> · '+ls[0].grammar;
} else el.style.display='none';
}
function updateBar(){
const len=queue.length||1;
bar.style.width=(Math.min(idx,len)/len*100)+"%";
counter.textContent = (mode==='unterricht'||mode==='stats')?'' : `${Math.min(idx+1,queue.length)} / ${queue.length}`;
scoreEl.textContent = total>0 ? `✓ ${correct}/${total}` : "";
}
function next(ok){
total++; if(ok)correct++;
const it=queue[idx];
if(it && it.id) bump(it.id, ok);
if(!ok && it) queue.push(it);
idx++; render();
}
function render(){
updateBar();
if(mode==='stats'){ renderStats(); return; }
if(mode==='unterricht'){ renderUnterricht(); return; }
if((GENERIC.includes(mode)||mode==='particle') && queue.length===0){
let msg;
if(mode==='weak')
msg=`<div style="font-size:40px">💪</div><h2>Keine schwachen Karten!</h2>
<p>Alles sitzt gerade gut. Mach eine Runde <b>🔁 Wiederholen</b>, dann füllt sich hier wieder was.</p>
<button class="btn btn-primary" onclick="start('review')">Zum Wiederholen</button>`;
else if(deckFor(mode).length===0)
msg=`<div style="font-size:40px">📭</div><h2>Keine Aufgaben hier</h2>
<p>Diese Lektion hat für diesen Modus keine Karten. Wähle oben eine andere Lektion oder einen anderen Reiter.</p>`;
else if(!sessionAll)
msg=`<div style="font-size:40px">✅</div><h2>Für heute erledigt!</h2>
<p>Diese Übung hast du heute schon komplett durch. Morgen kommen die Karten automatisch wieder.</p>
<button class="btn btn-primary" onclick="start('${mode}',true)">Trotzdem nochmal (alle)</button>`;
else
msg=`<div style="font-size:40px">🎉</div><h2>Nichts mehr zu üben.</h2>`;
app.innerHTML=`<div class="card empty">${msg}</div>`; bar.style.width='100%'; return;
}
if(idx>=queue.length){ done(); return; }
if(mode==='particle'){ renderParticle(); return; }
renderCard();
}
function done(){
const pct=total?Math.round(correct/total*100):0;
app.innerHTML=`<div class="card done">
<div class="big">${pct>=80?"🎉":pct>=50?"👍":"💪"}</div>
<h2>Fertig!</h2><p>${correct} von ${total} richtig · ${pct}%</p>
<button class="btn btn-primary" onclick="start('${mode}',true)">Nochmal</button></div>`;
bar.style.width="100%";
}
/* ========== GENERISCHE KARTE (Selbstkontrolle ODER Tippen) ========== */
function methodToggle(hasType){
const dirSel = (mode==='vocab')
? `<select class="sel" id="dir">
<option value="deJp"${dir==='deJp'?' selected':''}>DE → JP</option>
<option value="jpDe"${dir==='jpDe'?' selected':''}>JP → DE</option></select>` : '';
const mSel = hasType
? `<select class="sel" id="method">
<option value="self"${method==='self'?' selected':''}>Selbstkontrolle</option>
<option value="type"${method==='type'?' selected':''}>Tippen</option></select>` : '';
return `<div class="barctl"><span class="prompt-label">${modeLabel()}</span><span>${dirSel} ${mSel}</span></div>`;
}
function modeLabel(){
return {review:'Wiederholen',vocab:dir==='deJp'?'Deutsch → 日本語':'日本語 → Deutsch',
verbstem:'Verbstamm bilden',sentence:'Satz bauen',phrases:'Unterrichts-Satz',
adj:'Adjektiv verneinen'}[mode]||'';
}
function renderCard(){
const it=queue[idx];
const hasType = !!it.typeTarget;
const useType = hasType && method==='type';
app.innerHTML=`<div class="card">
${methodToggle(hasType)}
${it.front}
<div id="ans" class="hidden">${it.back}${it.id?('<div class="reading" style="margin-top:8px">Level: '+boxesHtml(it.id)+'</div>'):''}</div>
<div id="io"></div>
<div class="tip">${useType?'Tippe Kana <b>oder</b> Rōmaji (z.B. „tabe" → たべ). Enter prüft.':'Sag die Antwort <b>laut</b>, bevor du aufdeckst.'}</div>
</div>`;
const d=document.getElementById('dir'); if(d) d.onchange=e=>{dir=e.target.value;localStorage.setItem('kody_dir',dir);start('vocab');};
const mm=document.getElementById('method'); if(mm) mm.onchange=e=>{method=e.target.value;localStorage.setItem('kody_method',method);render();};
const io=document.getElementById('io');
if(useType){
io.innerHTML=`<input class="type" id="inp" autocomplete="off" autocapitalize="off" spellcheck="false" placeholder="…">
<div id="fb" class="feedback"></div>
<button class="btn btn-primary" id="chk" style="margin-top:14px">Prüfen</button>`;
const inp=document.getElementById('inp'); inp.focus();
const check=()=>{
const ok = norm(inp.value)===norm(it.typeTarget);
document.getElementById('ans').classList.remove('hidden');
inp.classList.add(ok?'ok':'bad');
document.getElementById('fb').innerHTML = ok
? '<span style="color:var(--green)">✓ Richtig!</span>'
: `<span style="color:var(--wo)">Du: ${toKana(inp.value)||'—'} · Richtig: ${it.typeTarget}</span>`;
document.getElementById('io').querySelector('#chk').outerHTML =
ok ? `<button class="btn btn-primary" style="margin-top:14px" onclick="next(true)">Weiter →</button>`
: `<div class="btn-row"><button class="btn btn-no" onclick="next(false)">Weiter (falsch)</button>
<button class="btn btn-ok" onclick="next(true)">War doch richtig ✓</button></div>`;
};
document.getElementById('chk').onclick=check;
inp.addEventListener('keydown',e=>{if(e.key==='Enter')check();});
} else {
io.innerHTML=`<button class="btn btn-primary" style="margin-top:16px" onclick="reveal()">Antwort zeigen</button>`;
window.reveal=()=>{
document.getElementById('ans').classList.remove('hidden');
io.innerHTML=`<div class="btn-row">
<button class="btn btn-no" onclick="next(false)">✗ Nochmal</button>
<button class="btn btn-ok" onclick="next(true)">✓ Gewusst</button></div>`;
};
}
}
/* ========== PARTIKEL ========== */
let pFill=[], activeSlot=0;
function renderParticle(){
const q=queue[idx]; pFill=q.ans.map(()=>null); let slot=-1;
const html=q.parts.map(p=>{ if(p==="___"){slot++;const s=slot;return `<span class="slot" id="slot${s}" onclick="selSlot(${s})">_</span>`;} return p;}).join(" ");
app.innerHTML=`<div class="card">
<span class="prompt-label">Setz die Partikel ein</span>
<div class="en" style="margin-bottom:6px">${q.hint}</div>
<div class="blanks">${html}</div>
<div class="choices">${CHOICES.map(c=>`<button onclick="pick('${c}')">${c}</button>`).join("")}</div>
<div id="fb" class="feedback"></div>
<div id="ctl"><button class="btn btn-primary" style="margin-top:16px" onclick="checkP()">Prüfen</button></div>
<div class="tip"><span class="p-ni">に</span> Ziel/Zweck · <span class="p-wo">を</span> Objekt · <span class="p-de">で</span> Ort der Handlung</div>
</div>`;
activeSlot=0; hi();
}
function hi(){document.querySelectorAll(".slot").forEach((s,i)=>s.style.background=i===activeSlot?"#fef6e8":"");}
window.selSlot=i=>{activeSlot=i;hi();};
window.pick=c=>{ pFill[activeSlot]=c; const el=document.getElementById("slot"+activeSlot); el.textContent=c; el.classList.add("filled"); if(activeSlot<pFill.length-1){activeSlot++;hi();}};
window.checkP=()=>{
const q=queue[idx]; const fb=document.getElementById("fb");
if(pFill.includes(null)){fb.innerHTML='<span style="color:var(--wo)">Erst alle Lücken füllen.</span>';return;}
const ok=pFill.every((p,i)=>p===q.ans[i]);
if(ok){ fb.innerHTML='<span style="color:var(--green)">✓ Perfekt!</span>'; document.querySelectorAll(".slot").forEach(s=>s.style.color="var(--green)");
document.getElementById("ctl").innerHTML=`<button class="btn btn-primary" style="margin-top:16px" onclick="next(true)">Weiter →</button>`;
}else{ fb.innerHTML='<span style="color:var(--wo)">Richtig: '+q.ans.join(" · ")+'</span>';
document.getElementById("ctl").innerHTML=`<button class="btn btn-primary" style="margin-top:16px" onclick="next(false)">Weiter →</button>`; }
};
/* ========== FORTSCHRITT / STATISTIK ========== */
function renderStats(){
bar.style.width="100%"; counter.textContent=''; scoreEl.textContent='';
const meta=allMeta();
let att=0, mastered=0, right=0, wrong=0, last=0, newCount=0;
meta.forEach(m=>{const r=STATS[m.id];
if(r&&(r.right+r.wrong>0)){att++; right+=r.right; wrong+=r.wrong; if(r.box>=4)mastered++; if(r.last>last)last=r.last;}
else newCount++;});
const acc = (right+wrong)? Math.round(right/(right+wrong)*100) : 0;
const weak=weakList().slice(0,12);
const strong=meta.filter(m=>{const r=STATS[m.id]; return r&&r.box>=4;}).slice(0,12);
const lastTxt = last? new Date(last).toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit',year:'2-digit',hour:'2-digit',minute:'2-digit'}) : '—';
const rowHtml=(m)=>{const r=STATS[m.id]||{right:0,wrong:0};
return `<div class="row"><span class="lbl">${m.label}</span>
<span class="rt">${boxesHtml(m.id)} &nbsp;<span class="ok">✓${r.right}</span> <span class="bad">✗${r.wrong}</span></span></div>`;};
app.innerHTML=`
<div class="tiles">
<div class="tile"><b>${att}</b><span>geübt</span></div>
<div class="tile"><b>${mastered}</b><span>gemeistert</span></div>
<div class="tile"><b>${acc}%</b><span>Genauigkeit</span></div>
</div>
<div class="note">Von ${meta.length} Karten sind ${newCount} noch neu. Zuletzt geübt: ${lastTxt}.</div>
<h2 class="section">⚠️ Schwach — üben!</h2>
${weak.length? `<button class="btn btn-primary" style="margin-bottom:10px" onclick="start('weak')">🎯 Nur diese ${weakList().length} schwachen Karten üben</button>
${weak.map(rowHtml).join("")}` : `<div class="empty">Noch keine Schwachstellen — oder noch nichts geübt. 🙂</div>`}
<h2 class="section">💪 Stark</h2>
${strong.length? strong.map(rowHtml).join("") : `<div class="empty">Noch keine gemeisterten Karten. Üben lohnt sich!</div>`}
<button class="btn btn-reset" onclick="resetStats()">🗑️ Fortschritt zurücksetzen</button>`;
}
window.resetStats=()=>{ if(confirm('Wirklich den gesamten Lernfortschritt löschen?')){ STATS={}; saveStats(); localStorage.removeItem('kody_leitner'); renderStats(); } };
/* ========== UNTERRICHT (Verhalten + Sätze) ========== */
function renderUnterricht(){
bar.style.width="100%";
app.innerHTML=`<div class="card">
<span class="prompt-label">Verhalten im Unterricht</span>
<ul class="beh">
<li><b>Aktiv sprechen.</b> Antworte in ganzen Sätzen — dein Ziel ist Produktion, nicht nur Verstehen.</li>
<li><b>Nicht schweigen.</b> Wenn du hängst, sag es auf Japanisch: „ちょっと待ってください" statt Pause.</li>
<li><b>Nachfragen auf Japanisch.</b> Nutze die Sätze unten, statt ins Deutsche/Englische zu wechseln.</li>
<li><b>Laut & deutlich.</b> Lieber falsch und laut als richtig und leise.</li>
<li><b>Mitschreiben.</b> Neue Wörter sofort in die App / Notizen.</li>
<li><b>Begrüßung:</b> zu Beginn „よろしくお願いします", am Ende „ありがとうございました".</li>
</ul>
<button class="btn btn-primary" style="margin-top:18px" onclick="start('phrases')">🎯 Diese Sätze üben (DE → JP)</button>
</div>
<h2 class="section">Nützliche Sätze im Unterricht</h2>
${PHRASES.map(p=>`<div class="phrase"><div class="jp">${p.jpr}</div><div class="reading">${p.read}</div><div class="de">${p.de}</div></div>`).join("")}`;
counter.textContent=''; scoreEl.textContent='';
}
/* ========== INIT ========== */
function fillLessonSel(){
const sel=document.getElementById('lessonSel');
let html=LESSONS.map(l=>`<option value="${l.id}">${l.code} · ${l.title}</option>`).join('');
if(LESSONS.length>1) html+=`<option value="all">🔀 Alle Lektionen (gemischt)</option>`;
sel.innerHTML=html; sel.value=lesson;
sel.onchange=e=>{ lesson=e.target.value; localStorage.setItem('kody_lesson',lesson); start(mode); };
}
fillLessonSel();
document.querySelectorAll("nav button").forEach(b=>b.onclick=()=>start(b.dataset.mode));
start("review");
</script>
</body>
</html>