File size: 32,786 Bytes
5cf774c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
const assets = {
  calendar: "assets/materials/mq3zhq9n-clipboard.png",
  slide: "assets/materials/mq3zhqat-clipboard.png",
  notes: "assets/materials/mq3zhqbu-clipboard.png",
  evidence: "assets/materials/mq3zhqdk-clipboard.png",
  recent: [
    "assets/materials/mq3zhqe0-clipboard.png",
    "assets/materials/mq3zhqe3-clipboard.png",
    "assets/materials/mq3zhqea-clipboard.png",
    "assets/materials/mq3zhqeg-clipboard.png"
  ]
};

const routes = ["overview", "uploads", "canvas", "calendar", "learning-plan", "gaps", "flashcards", "quiz", "reminders"];
const app = document.querySelector("#app");
const navList = document.querySelector("#navList");
const toast = document.querySelector("#toast");

const pageHead = (title, subtitle, actions = "") => `
  <header class="page-head">
    <div><h1>${title}</h1><p>${subtitle}</p></div>
    <div class="head-actions">${actions}</div>
  </header>`;

const panel = (title, body, extra = "", className = "") => `
  <section class="panel ${className}">
    <div class="panel-head"><h2>${title}</h2>${extra || '<span class="more">...</span>'}</div>
    ${body}
  </section>`;

function overviewPage() {
  const agenda = [
    ["09:00", "Mehrsprachigkeitsdidaktik", "Seminar im Hörsaal 3 · Sprachbewusstsein & Transferstrategien", "book-open", "green"],
    ["11:30", "Englischdidaktik", "Übung · Classroom Interaction & Feedback", "globe", "blue"],
    ["13:00", "Mittagspause", "Zeit für gutes Essen und einen kurzen Spaziergang am Rhein", "fork-knife", "rose"],
    ["15:00", "Lernblock Bildungspsychologie", "Kapitel 4: Motivation & Selbstregulation · Karteikarten erstellen", "brain", "aubergine"],
    ["17:30", "Familie & Freunde", "Abendessen bei Mama & Papa", "users-three", "gold"]
  ].map(([time, title, sub, icon, tone]) => `
    <button class="day-entry ${tone}" data-route="${time === "15:00" ? "canvas" : "calendar"}">
      <time>${time}</time>
      <span class="day-icon"><i class="ph ph-${icon}"></i></span>
      <span><strong>${title}</strong><small>${sub}</small></span>
      <i class="ph ph-caret-right entry-arrow"></i>
    </button>`).join("");

  return `
    <div class="josephine-home">
      <section class="josephine-hero">
        <img src="assets/hero/josephine-mainz-morning.png" alt="Josephine lernt an einem sonnigen Morgen in Mainz, umgeben von Erinnerungen an Familie, Freunde und ihr Lieblingspferd.">
        <div class="weather-line">Dienstag, 7. Juni <span>·</span> Mainz <span>·</span> 18° <i class="ph ph-sun"></i></div>
        <div class="hero-copy">
          <h1>Josephine<br>Wendland</h1>
          <p class="hero-motto">Lehren. Verstehen. Verbinden.</p>
          <h2>Guten Morgen, Josephine</h2>
          <p>Heute ist ein guter Tag, etwas zu lernen,<br>zu wachsen und Menschen zu inspirieren.</p>
        </div>
      </section>

      <section class="daily-journal">
        <div class="journal-agenda">
          <header><i class="ph ph-calendar-blank"></i><h2>Mein Tag</h2><span>7. Juni</span></header>
          <div class="day-list">${agenda}</div>
        </div>
        <aside class="today-important">
          <header><i class="ph ph-star"></i><h2>Heute wichtig</h2></header>
          <button class="important-row deadline" data-route="calendar">
            <span class="important-icon"><i class="ph ph-calendar-dots"></i></span>
            <span><small>Deadline</small><strong>Reflexionsbericht Mehrsprachigkeit</strong><em>Abgabe: Freitag, 10. Juni</em></span>
            <i class="ph ph-caret-right"></i>
          </button>
          <button class="important-row gap" data-route="gaps">
            <span class="important-icon"><i class="ph ph-target"></i></span>
            <span><small>Wissenslücke</small><strong>Selbstwirksamkeit verstehen</strong><em>Wiederholen · Karte 24–27</em></span>
            <i class="ph ph-caret-right"></i>
          </button>
          <button class="important-row next" data-route="canvas">
            <span class="important-icon"><i class="ph ph-book-open"></i></span>
            <span><small>Nächster Schritt</small><strong>Lernen fortsetzen</strong><em>Bildungspsychologie · Kapitel 4</em></span>
            <i class="ph ph-caret-right"></i>
          </button>
          <p class="journal-note">Kleine Schritte jeden Tag<br>führen zu großen Veränderungen.</p>
        </aside>
      </section>
    </div>`;
}

function uploadsPage() {
  const extracted = `Sprachbewusstheit fördern (VL 07)

Begriff: Fähigkeit, Sprache(n) als System(e) wahrzunehmen und über Sprache(n) nachzudenken.

Ziele:
- Sensibilisierung für sprachliche Strukturen und Variation
- Vergleich von Sprachen als Ressourcen nutzen
- Transferstrategien entwickeln

Vergleich DE - FR
DE: Ich gehe in die Schule.
FR: Je vais à l'école.

Gemeinsamkeiten: Subjekt - Verb - Objekt
Unterschiede: Artikel, Präpositionen, Akkordanz

Didaktische Prinzipien:
1) Sprachenvergleich
2) Bewusstmachung
3) Funktionaler Einsatz im Fachunterricht`;

  return pageHead("Materialien", "Notizen, Folien und Kalender an einem ruhigen Ort.", `
    <button class="button secondary" id="addFiles">Dateien hinzufügen</button>
    <button class="button primary" data-route="canvas">In Arbeitsfläche öffnen</button>
  `) + `
  <div class="uploads-grid">
    ${panel("Upload-Queue (3)", `<div class="queue-list">
      <div class="queue-item selected"><div class="queue-title"><strong>Mehrsprachigkeitsdidaktik_VL07.pdf</strong><span class="badge green">100%</span></div><div class="progress"><span style="width:100%"></span></div><small>OCR abgeschlossen · 32 Seiten</small></div>
      <div class="queue-item"><div class="queue-title"><strong>Englischdidaktik_Orthografie.pdf</strong><span class="badge blue">76%</span></div><div class="progress"><span style="width:76%;background:var(--blue)"></span></div><small>OCR läuft · Seite 3 von 11</small></div>
      <div class="queue-item"><div class="queue-title"><strong>Bildungspsychologie_Notizen.jpg</strong><span class="badge">0%</span></div><div class="progress"><span style="width:0%"></span></div><small>Wartet in der Queue</small></div>
      <div class="dropzone" id="dropzone"><strong>Dateien hier ablegen</strong><br><small>PDF, JPG oder PNG · Verarbeitung bleibt lokal</small></div>
    </div>`, '<span class="badge green">Lokal</span>', "upload-queue")}
    ${panel("Mehrsprachigkeitsdidaktik_VL07.pdf", `<div class="doc-review">
      <div class="doc-pane"><div class="doc-toolbar"><button class="icon-button">‹</button><span>4 / 32</span><button class="icon-button">›</button><span>100%</span><button class="icon-button">↗</button></div><div class="document-page"><img src="${assets.slide}" alt="Vorlesungsfolie zu Scaffolding im mehrsprachigen Unterricht"></div></div>
      <div class="note-pane"><img src="${assets.notes}" alt="Handschriftliche Notizen zu Scaffolding im mehrsprachigen Unterricht"></div>
    </div>`, '<span class="badge blue">Seite 4 verknüpft</span>')}
    ${panel("OCR-Extraktion", `<div class="panel-body ocr-panel">
      <div class="language-tabs"><button class="badge green">Deutsch 99%</button><button class="badge blue">Französisch 82%</button><button class="badge">Englisch 12%</button></div>
      <div class="confidence">Konfidenz der Seite: <strong>93%</strong> · 7 Markierungen prüfen</div>
      <label class="field"><span class="label">Extrahierter Text</span><textarea id="ocrText">${extracted}</textarea></label>
      <div class="row" style="justify-content:space-between"><span class="badge amber">Niedrige Konfidenz: Akkordanz</span><button class="button secondary" id="reviewAll">Alle prüfen</button></div>
      <div class="ocr-actions"><button class="button secondary">Verwerfen</button><button class="button primary" id="saveOcr">Übernehmen &amp; speichern</button></div>
      <div class="trust-inline">Speichern in: Mehrsprachigkeitsdidaktik · nur lokal</div>
    </div>`, '<span class="badge green">Abgeschlossen</span>')}
  </div>`;
}

function canvasPage() {
  const thumbs = [assets.recent[0], assets.recent[1], assets.slide, assets.recent[2], assets.recent[3]]
    .map((src, i) => `<button class="slide-thumb ${i === 2 ? "active" : ""}" data-slide="${i}"><img src="${src}" alt="Materialvorschau ${i + 1}"></button>`).join("");
  return `<div class="canvas-page">
    <header class="canvas-head">
      <h1>Smart Study Canvas <span>Mehrsprachigkeitsdidaktik / Woche 7</span></h1>
      <div class="head-actions"><button class="button secondary">Verknüpfungen</button><button class="button secondary">Notiz hinzufügen</button><button class="button secondary">Exportieren</button></div>
    </header>
    <div class="canvas-grid">
      ${panel("Vorlesungsfolien", `<div class="slide-workspace"><div class="slide-thumbs">${thumbs}</div><div class="slide-main"><img id="mainSlide" src="${assets.slide}" alt="Vorlesungsfolie Scaffolding"></div></div>`)}
      ${panel("Handschriftliche Notizen", `<div class="notes-main"><img src="${assets.notes}" alt="Maya Hoffmanns handschriftliche Scaffolding-Notizen"></div>`, '<span class="badge blue">4 semantische Links</span>')}
      ${panel("AI-Copilot", `<div class="chat"><div class="messages" id="messages">
        <div class="message user">Wie hängen Translanguaging und Scaffolding zusammen?</div>
        <div class="message ai"><strong>Maya</strong><br>Scaffolding schafft temporäre sprachliche und kognitive Stützen. Translanguaging erlaubt Lernenden, ihr gesamtes sprachliches Repertoire für Bedeutungsbildung zu nutzen. Zusammen fördern sie fachliche Teilhabe, ohne die Zielsprache auszublenden.<div class="language-tabs"><span class="badge green">Folie 14</span><span class="badge blue">Notiz S. 1</span></div></div>
        <div class="alert-card"><strong>Fehlendes Konzept erkannt: Interlanguage</strong>Die Unterscheidung zur Interlanguage fehlt in deinen verknüpften Notizen.<div class="language-tabs"><button class="badge">Konzept erklären</button><button class="badge">Quelle suchen</button><button class="badge">Karte erstellen</button></div></div>
      </div><form class="chat-compose" id="chatForm"><input id="chatInput" placeholder="Stelle eine Frage zu deinen Materialien..." required><button class="button primary" aria-label="Senden">➤</button></form></div>`, '<span class="badge green">Lokal · Quellengebunden</span>')}
    </div>
  </div>`;
}

function calendarPage() {
  const cells = Array.from({length: 35}, () => "<div></div>").join("");
  const roadmapRows = [
    ["Mehrsprachigkeitsdidaktik","on,on,on,,blue,blue,,"],
    ["Englischdidaktik","blue,blue,,on,on,,,"],
    ["Französischdidaktik",",amber,amber,,on,on,,"],
    ["Bildungspsychologie","on,,blue,blue,,on,on,on"]
  ].map(([name, states]) => `<b>${name}</b>${states.split(",").map(s => `<span class="${s}"></span>`).join("")}`).join("");
  return pageHead("Kalender & Lernplan", "Geprüfte Termine, realistische Lernblöcke und dein 8-Tage-Fokus.", `
    <button class="button secondary" id="reviewExtractions">Extraktionen prüfen · 3</button>
    <button class="button primary" id="planBlock">Lernblock planen</button>
  `) + `
  <div class="calendar-grid">
    ${panel("Wochenplan · 7.-11. Juni", `<div class="week-grid">
      <div></div>${["Di 7.","Mi 8.","Do 9.","Fr 10.","Sa 11."].map(d=>`<div class="day">${d}</div>`).join("")}
      ${["09:00","10:00","11:00","12:00","13:00","14:00","15:00"].map(t=>`<div class="time">${t}</div>`).join("")}${cells}
      <div class="event" style="grid-column:2;grid-row:2/4"><strong>09:00</strong><br>Mehrsprachigkeitsdidaktik<br>Seminar</div>
      <div class="event amber" style="grid-column:3;grid-row:3/5"><strong>10:00</strong><br>Hausarbeit<br>Quellenarbeit</div>
      <div class="event blue" style="grid-column:4;grid-row:4/6"><strong>11:00</strong><br>Französischdidaktik<br>Séance 5</div>
      <div class="event" style="grid-column:5;grid-row:2/5"><strong>09:00</strong><br>Fachdidaktik Deutsch<br>Portfolio</div>
      <div class="event blue" style="grid-column:6;grid-row:3/5"><strong>10:00</strong><br>Lerngruppe<br>Bibliothek</div>
    </div><div class="roadmap"><h3>8-Tage-Prüfungsroadmap</h3><div class="roadmap-grid"><b></b>${["Di 7","Mi 8","Do 9","Fr 10","Sa 11","So 12","Mo 13","Di 14"].map(d=>`<b>${d}</b>`).join("")}${roadmapRows}</div><p class="muted" style="font-size:10px">Fokus: Hausarbeit abschließen → Französischdidaktik wiederholen → Prüfungssimulation</p></div>`, '<span class="badge green">72% geplant</span>', "week-calendar")}
    <div class="stack">
      ${panel("Heute · 5 Std. 30 Min.", `<div class="panel-body"><div class="today-block"><strong>09:00-10:30 · Seminarfolien</strong><small>Translanguaging und Scaffolding verknüpfen</small></div><div class="today-block"><strong>11:30-13:00 · Reading response</strong><small>Englischdidaktik · Kapitel 4</small></div><div class="today-block"><strong>15:00-16:30 · Retrieval Practice</strong><small>Bildungspsychologie · Lernkarten 31-54</small></div></div>`, '<span class="badge green">Im Plan</span>')}
      ${panel("Geprüfte Extraktionen", `<div class="panel-body"><div class="extraction-row"><span>10. Juni</span><strong>Hausarbeit abgeben</strong><span class="badge amber">Bestätigt</span></div><div class="extraction-row"><span>14. Juni</span><strong>Französischdidaktik Prüfung</strong><span class="badge blue">Kalender</span></div><div class="extraction-row"><span>19. Juni</span><strong>Portfolio Deutsch</strong><span class="badge green">Bestätigt</span></div><img class="calendar-asset" src="${assets.calendar}" alt="Handschriftlicher Kalender Juni 2025"></div>`, '<span class="badge">3 aus PDF</span>')}
    </div>
  </div>`;
}

function flashcardsPage() {
  const decks = [
    ["Mehrsprachigkeitsdidaktik",48,"18 fällig · zuletzt heute",72],
    ["Englischdidaktik",36,"Nächste Wiederholung morgen",58],
    ["Französischdidaktik",42,"Nächste Wiederholung morgen",44],
    ["Bildungspsychologie",61,"Nächste Wiederholung morgen",81],
    ["Fachdidaktik Deutsch",27,"Nächste Wiederholung morgen",36]
  ].map(([name,count,sub,pct],i)=>`<div class="deck-row ${i===0?"selected":""}" data-deck="${name}"><strong>${name} · ${count} Karten</strong><small>${sub}</small><div class="progress"><span style="width:${pct}%"></span></div></div>`).join("");
  return pageHead("Karteikarten", "Quellengebundene Karten bearbeiten, lernen und exportieren.", `
    <button class="button secondary" id="generateCards">Aus Quellen generieren</button>
    <button class="button primary" id="learnCards">12 Karten lernen</button>
  `) + `
  <div class="cards-grid">
    ${panel("Meine Decks", `<div>${decks}</div>`)}
    ${panel("Karte bearbeiten · 12 von 48", `<div class="panel-body">
      <div class="field question"><label for="cardQuestion">Frage</label><textarea id="cardQuestion">Wie unterscheidet sich Translanguaging vom klassischen Code-Switching?</textarea></div>
      <div class="field answer"><label for="cardAnswer">Antwort</label><textarea id="cardAnswer">Translanguaging beschreibt die flexible Nutzung des gesamten sprachlichen Repertoires zur Bedeutungsbildung. Code-Switching bezeichnet dagegen meist den situativen Wechsel zwischen getrennt gedachten Sprachen.</textarea></div>
      <div class="field"><label>Quellen</label><div class="source-box">▣ Mehrsprachigkeitsdidaktik_Woche_7.pdf · Folie 14<br>▤ Notizen_Scaffolding_03-06.jpg · Seite 1</div><div class="evidence-strip"><img src="${assets.evidence}" alt="Quellenausschnitt aus einer Notiz"><img src="${assets.notes}" alt="Handschriftliche Evidenz zu Scaffolding"></div></div>
      <div class="language-tabs"><span class="badge green">Translanguaging</span><span class="badge blue">Code-Switching</span><span class="badge">Woche 7</span></div>
      <div class="row" style="justify-content:space-between"><button class="button danger" id="deleteCard">Karte löschen</button><button class="button primary" id="saveCard">Änderungen speichern</button></div>
    </div>`)}
    ${panel("Vorschau & Export", `<div class="panel-body stack"><div class="card-preview" id="cardPreview"><div class="front"><small>Vorderseite</small><strong>Wie unterscheidet sich Translanguaging vom klassischen Code-Switching?</strong><span class="muted">Klicken zum Umdrehen</span></div><div class="back"><small>Rückseite</small><p>Translanguaging nutzt das gesamte sprachliche Repertoire flexibel. Code-Switching beschreibt den situativen Wechsel zwischen getrennt gedachten Sprachen.</p></div></div><div class="divider"></div><h3 style="font-family:var(--serif);margin:2px 0">Deck exportieren</h3><span class="muted" style="font-size:11px">48 Karten · Quellen enthalten · DE</span><div class="export-list"><button class="button" data-export="Anki">Anki (.apkg)</button><button class="button" data-export="CSV">CSV</button><button class="button" data-export="PDF">PDF zum Drucken</button></div><small class="muted">Letzte Generierung: heute, 10:42 · vollständig lokal</small></div>`)}
  </div>`;
}

function quizPage() {
  return pageHead("Quizmodus", "Prüfungssimulation · Mehrsprachigkeitsdidaktik", `<button class="button secondary" id="endQuiz">Simulation beenden</button>`) + `
  <div class="quiz-grid">
    ${panel("Frage 7 von 12", `<div class="quiz-content">
      <div class="quiz-meta"><span class="muted">Fortschritt · <span id="quizProgressText">58%</span></span><span class="badge amber">Schwierigkeit: Anspruchsvoll</span></div>
      <div class="progress"><span id="quizProgress" style="width:58%"></span></div>
      <h2 class="quiz-question">Welche Aussage beschreibt den didaktischen Nutzen von Translanguaging am präzisesten?</h2>
      <div class="answers" id="answers">
        <button class="answer-option" data-answer="A"><span class="answer-letter">A</span><span>Es verhindert den Wechsel zwischen Unterrichtssprachen vollständig.</span></button>
        <button class="answer-option" data-answer="B"><span class="answer-letter">B</span><span><strong>Es aktiviert das gesamte sprachliche Repertoire zur Bedeutungsbildung und fachlichen Teilhabe.</strong></span></button>
        <button class="answer-option" data-answer="C"><span class="answer-letter">C</span><span>Es ersetzt fachsprachliche Lernziele durch alltagssprachliche Kommunikation.</span></button>
        <button class="answer-option" data-answer="D"><span class="answer-letter">D</span><span>Es ist ausschließlich für den Fremdsprachenunterricht geeignet.</span></button>
      </div>
      <div class="explanation" id="quizExplanation" hidden><h3 id="answerState">Richtig beantwortet</h3><p>Translanguaging nutzt vorhandene sprachliche Ressourcen gezielt als Brücke zum fachlichen Verstehen. Die Zielsprache bleibt wichtig, wird aber nicht als isoliertes System behandelt.</p><div class="source-citation">Quelle: Mehrsprachigkeitsdidaktik_Woche_7.pdf · Folie 14<br>„Dynamische Nutzung des gesamten sprachlichen Repertoires zur Bedeutungskonstruktion.“</div><div class="row" style="justify-content:space-between;margin-top:14px"><small class="muted" id="chosenAnswer"></small><button class="button primary" id="nextQuestion">Nächste Frage →</button></div></div>
    </div>`, '<span class="more">...</span>', "quiz-card")}
    <div class="stack">
      ${panel("Simulationsstatus", `<div class="panel-body"><div class="stats-grid"><div class="stat"><strong id="correctCount">5</strong><small>richtig</small></div><div class="stat"><strong id="wrongCount">1</strong><small>falsch</small></div><div class="stat"><strong id="hitRate">82%</strong><small>Trefferquote</small></div><div class="stat"><strong id="timer">06:42</strong><small>verbleibend</small></div></div></div>`)}
      ${panel("Schwierigkeit", `<div class="panel-body"><div class="difficulty"><button data-level="Adaptiv">Adaptiv</button><button data-level="Mittel">Mittel</button><button class="active" data-level="Anspruchsvoll">Anspruchsvoll</button></div><p class="muted" style="font-size:11px">Die nächsten Fragen gewichten deine Wissenslücken stärker.</p></div>`)}
      ${panel("Prüfungsfokus", `<div class="panel-body"><div class="focus-list"><div><span class="badge red">Lücke</span> Interlanguage</div><div><span class="badge amber">Prüfen</span> Scaffolding</div><div><span class="badge green">Sicher</span> Translanguaging</div></div><div class="divider" style="margin:14px 0"></div><small class="muted">12 Fragen · 15 Minuten<br>Nur aus 3 ausgewählten lokalen Quellen</small></div>`)}
    </div>
  </div>`;
}

function learningPlanPage() {
  return pageHead("Mein Lernplan", "Ein realistischer Plan, der zu Josephines Woche passt.", `
    <button class="button secondary" data-route="calendar">Kalender ansehen</button>
    <button class="button primary" data-route="canvas">Lernblock starten</button>
  `) + `
  <div class="quiet-page">
    <section class="plan-intro">
      <span class="eyebrow">Prüfung in 8 Tagen</span>
      <h2>Diese Woche zählt Beständigkeit,<br>nicht Perfektion.</h2>
      <p>StudyFlow verbindet deine Termine, Materialien und offenen Themen zu kleinen, machbaren Schritten.</p>
    </section>
    <div class="plan-days">
      <button data-route="canvas"><time>Heute</time><strong>Grundlagen wiederholen</strong><span>Mehrsprachigkeitsdidaktik · 75 Min.</span></button>
      <button data-route="flashcards"><time>Morgen</time><strong>Scaffolding vertiefen</strong><span>Folien, Notizen und 12 Karten · 60 Min.</span></button>
      <button data-route="quiz"><time>Donnerstag</time><strong>Formative Bewertung üben</strong><span>Quiz und Reflexion · 45 Min.</span></button>
      <button data-route="gaps"><time>Freitag</time><strong>Wissenslücken schließen</strong><span>Selbstwirksamkeit und Interlanguage · 60 Min.</span></button>
    </div>
  </div>`;
}

function gapsPage() {
  return pageHead("Wissenslücken", "Was noch unsicher ist, wird hier verständlich und machbar.", `
    <button class="button primary" data-route="quiz">Kurzes Quiz starten</button>
  `) + `
  <div class="quiet-page two-column">
    <section class="focus-story">
      <span class="eyebrow">Heute empfohlen</span>
      <h2>Selbstwirksamkeit verstehen</h2>
      <p>In deinen Notizen fehlt noch die Verbindung zwischen Selbstwirksamkeit, Motivation und Lernerfolg.</p>
      <button class="button primary" data-route="canvas">Mit Quellen erklären</button>
    </section>
    <section class="calm-list">
      <button data-route="canvas"><span class="signal red"></span><span><strong>Interlanguage</strong><small>Nur indirekt in drei Quellen erklärt</small></span><em>Hoch</em></button>
      <button data-route="flashcards"><span class="signal amber"></span><span><strong>Scaffolding</strong><small>Zwei unsichere Karten</small></span><em>Mittel</em></button>
      <button data-route="canvas"><span class="signal green"></span><span><strong>Translanguaging</strong><small>Quellenlage vollständig</small></span><em>Sicher</em></button>
    </section>
  </div>`;
}

function remindersPage() {
  return pageHead("Erinnerungen", "Freundliche Hinweise, damit Wichtiges nicht im Alltag untergeht.", `
    <button class="button primary" id="newReminder">Erinnerung hinzufügen</button>
  `) + `
  <div class="quiet-page reminders-page">
    <section class="reminder-date"><span>Heute</span><strong>7. Juni</strong><p>Du hast einen ruhigen Abend ohne Studienfrist.</p></section>
    <section class="calm-list">
      <button data-route="calendar"><span class="important-icon"><i class="ph ph-file-text"></i></span><span><strong>Reflexionsbericht Mehrsprachigkeit</strong><small>Freitag, 10. Juni · 23:59</small></span><em>In 3 Tagen</em></button>
      <button data-route="calendar"><span class="important-icon"><i class="ph ph-presentation-chart"></i></span><span><strong>Französische Präsentation</strong><small>Montag, 13. Juni · 10:00</small></span><em>In 6 Tagen</em></button>
      <button data-route="learning-plan"><span class="important-icon"><i class="ph ph-book-open"></i></span><span><strong>Bildungspsychologie wiederholen</strong><small>Morgen · 15:00</small></span><em>Geplant</em></button>
    </section>
  </div>`;
}

const renderers = {
  overview: overviewPage,
  uploads: uploadsPage,
  canvas: canvasPage,
  calendar: calendarPage,
  "learning-plan": learningPlanPage,
  gaps: gapsPage,
  flashcards: flashcardsPage,
  quiz: quizPage,
  reminders: remindersPage
};

function normalizeRoute() {
  const route = location.hash.replace("#/", "").replace("#", "");
  return routes.includes(route) ? route : "overview";
}

function navigate(route) {
  if (!routes.includes(route)) return;
  if (location.hash !== `#/${route}`) location.hash = `#/${route}`;
  else render();
}

function render() {
  const route = normalizeRoute();
  app.innerHTML = renderers[route]();
  navList.querySelectorAll("[data-route]").forEach(btn => btn.classList.toggle("active", btn.dataset.route === route));
  document.title = `${route === "overview" ? "Heute" : app.querySelector("h1")?.textContent || "StudyFlow"} · StudyFlow AI`;
  closeMenu();
  app.focus({ preventScroll: true });
  bindPage(route);
}

function bindPage(route) {
  app.querySelectorAll("[data-route]").forEach(el => el.addEventListener("click", () => navigate(el.dataset.route)));
  if (route === "uploads") bindUploads();
  if (route === "canvas") bindCanvas();
  if (route === "calendar") bindCalendar();
  if (route === "flashcards") bindFlashcards();
  if (route === "quiz") bindQuiz();
  if (route === "reminders") {
    document.querySelector("#newReminder")?.addEventListener("click", () => showToast("Neue Erinnerung wird lokal angelegt."));
  }
  app.querySelector("[data-action='open-plan']")?.addEventListener("click", () => navigate("calendar"));
}

function bindUploads() {
  const dropzone = document.querySelector("#dropzone");
  ["dragenter", "dragover"].forEach(type => dropzone.addEventListener(type, event => { event.preventDefault(); dropzone.classList.add("drag"); }));
  ["dragleave", "drop"].forEach(type => dropzone.addEventListener(type, event => { event.preventDefault(); dropzone.classList.remove("drag"); }));
  dropzone.addEventListener("drop", () => showToast("Datei zur lokalen Queue hinzugefügt."));
  document.querySelector("#addFiles").addEventListener("click", () => showToast("Dateiauswahl geöffnet. Demo bleibt lokal."));
  document.querySelector("#reviewAll").addEventListener("click", () => {
    document.querySelector("#ocrText").focus();
    showToast("7 unsichere Stellen sind zur Prüfung markiert.");
  });
  document.querySelector("#saveOcr").addEventListener("click", () => showToast("OCR-Text lokal gespeichert und verknüpft."));
}

function bindCanvas() {
  const mainSlide = document.querySelector("#mainSlide");
  const slideAssets = [assets.recent[0], assets.recent[1], assets.slide, assets.recent[2], assets.recent[3]];
  document.querySelectorAll(".slide-thumb").forEach(button => button.addEventListener("click", () => {
    document.querySelectorAll(".slide-thumb").forEach(item => item.classList.remove("active"));
    button.classList.add("active");
    mainSlide.src = slideAssets[Number(button.dataset.slide)];
  }));
  document.querySelector("#chatForm").addEventListener("submit", event => {
    event.preventDefault();
    const input = document.querySelector("#chatInput");
    const text = input.value.trim();
    if (!text) return;
    const messages = document.querySelector("#messages");
    messages.insertAdjacentHTML("beforeend", `<div class="message user">${escapeHtml(text)}</div><div class="message ai"><strong>Maya</strong><br>Ich prüfe diese Frage gegen die lokal verknüpften Folien und Notizen. Die relevanten Stellen liegen auf Folie 14 und in deiner Scaffolding-Notiz.</div>`);
    input.value = "";
    messages.scrollTop = messages.scrollHeight;
  });
}

function bindCalendar() {
  document.querySelector("#planBlock").addEventListener("click", () => showToast("Neuer Lernblock für 17:15 vorgeschlagen."));
  document.querySelector("#reviewExtractions").addEventListener("click", () => showToast("Drei bestätigte Termine aus lokalen Quellen."));
}

function bindFlashcards() {
  const preview = document.querySelector("#cardPreview");
  preview.addEventListener("click", () => preview.classList.toggle("flipped"));
  document.querySelector("#saveCard").addEventListener("click", () => showToast("Karte lokal gespeichert."));
  document.querySelector("#deleteCard").addEventListener("click", () => showToast("Karte zur Löschung vorgemerkt."));
  document.querySelector("#generateCards").addEventListener("click", () => showToast("6 Kartenvorschläge aus zwei Quellen erzeugt."));
  document.querySelector("#learnCards").addEventListener("click", () => showToast("Lernsession mit 12 fälligen Karten gestartet."));
  document.querySelectorAll("[data-export]").forEach(button => button.addEventListener("click", () => showToast(`${button.dataset.export}-Export lokal vorbereitet.`)));
  document.querySelectorAll(".deck-row").forEach(row => row.addEventListener("click", () => {
    document.querySelectorAll(".deck-row").forEach(item => item.classList.remove("selected"));
    row.classList.add("selected");
    showToast(`${row.dataset.deck} ausgewählt.`);
  }));
}

function bindQuiz() {
  const options = [...document.querySelectorAll(".answer-option")];
  const explanation = document.querySelector("#quizExplanation");
  options.forEach(option => option.addEventListener("click", () => {
    options.forEach(item => item.classList.remove("selected", "wrong"));
    const correct = option.dataset.answer === "B";
    option.classList.add(correct ? "selected" : "wrong");
    explanation.hidden = false;
    document.querySelector("#answerState").textContent = correct ? "Richtig beantwortet" : "Noch nicht richtig";
    document.querySelector("#answerState").style.color = correct ? "var(--emerald-dark)" : "var(--red)";
    document.querySelector("#chosenAnswer").textContent = `Antwort gewählt · ${option.dataset.answer}`;
  }));
  document.querySelectorAll("[data-level]").forEach(button => button.addEventListener("click", () => {
    document.querySelectorAll("[data-level]").forEach(item => item.classList.remove("active"));
    button.classList.add("active");
    showToast(`Schwierigkeit auf ${button.dataset.level} gesetzt.`);
  }));
  document.querySelector("#nextQuestion")?.addEventListener("click", () => {
    document.querySelector(".panel-head h2").textContent = "Frage 8 von 12";
    document.querySelector("#quizProgress").style.width = "67%";
    document.querySelector("#quizProgressText").textContent = "67%";
    showToast("Nächste Frage geladen.");
  });
  document.querySelector("#endQuiz").addEventListener("click", () => showToast("Simulation pausiert. Dein Stand bleibt lokal gespeichert."));
}

function showToast(message) {
  toast.textContent = message;
  toast.classList.add("show");
  clearTimeout(showToast.timer);
  showToast.timer = setTimeout(() => toast.classList.remove("show"), 2600);
}

function escapeHtml(value) {
  return value.replace(/[&<>"']/g, char => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#039;" }[char]));
}

const sidebar = document.querySelector("#sidebar");
const scrim = document.querySelector("#scrim");
const menuButton = document.querySelector("#menuButton");
function closeMenu() {
  sidebar.classList.remove("open");
  scrim.classList.remove("show");
  menuButton.setAttribute("aria-expanded", "false");
}
menuButton.addEventListener("click", () => {
  const open = sidebar.classList.toggle("open");
  scrim.classList.toggle("show", open);
  menuButton.setAttribute("aria-expanded", String(open));
});
scrim.addEventListener("click", closeMenu);
navList.addEventListener("click", event => {
  const button = event.target.closest("[data-route]");
  if (button) navigate(button.dataset.route);
});

document.querySelector("#askButton").addEventListener("click", () => document.querySelector("#aiDialog").showModal());
document.querySelector("#aiSubmit").addEventListener("click", () => {
  const prompt = document.querySelector("#aiPrompt").value.trim();
  showToast(prompt ? "Lokale Antwort wird aus 12 Materialien erzeugt." : "Bitte gib zuerst eine Frage ein.");
});
document.querySelector("#globalSearch").addEventListener("keydown", event => {
  if (event.key === "Enter" && event.currentTarget.value.trim()) showToast(`Lokale Suche nach „${event.currentTarget.value.trim()}“`);
});
document.addEventListener("keydown", event => {
  if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
    event.preventDefault();
    document.querySelector("#globalSearch").focus();
  }
  if (event.key === "Escape") closeMenu();
});
window.addEventListener("hashchange", render);
render();