@timmeck/brain-core 2.36.23 → 2.36.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/command-center.html +259 -153
  2. package/dist/active-learning/__tests__/active-learning.test.d.ts +1 -0
  3. package/dist/active-learning/__tests__/active-learning.test.js +132 -0
  4. package/dist/active-learning/__tests__/active-learning.test.js.map +1 -0
  5. package/dist/active-learning/active-learner.d.ts +79 -0
  6. package/dist/active-learning/active-learner.js +224 -0
  7. package/dist/active-learning/active-learner.js.map +1 -0
  8. package/dist/active-learning/index.d.ts +2 -0
  9. package/dist/active-learning/index.js +2 -0
  10. package/dist/active-learning/index.js.map +1 -0
  11. package/dist/code-health/__tests__/code-health.test.d.ts +1 -0
  12. package/dist/code-health/__tests__/code-health.test.js +123 -0
  13. package/dist/code-health/__tests__/code-health.test.js.map +1 -0
  14. package/dist/code-health/health-monitor.d.ts +55 -0
  15. package/dist/code-health/health-monitor.js +180 -0
  16. package/dist/code-health/health-monitor.js.map +1 -0
  17. package/dist/code-health/index.d.ts +2 -0
  18. package/dist/code-health/index.js +2 -0
  19. package/dist/code-health/index.js.map +1 -0
  20. package/dist/consensus/__tests__/consensus.test.d.ts +1 -0
  21. package/dist/consensus/__tests__/consensus.test.js +159 -0
  22. package/dist/consensus/__tests__/consensus.test.js.map +1 -0
  23. package/dist/consensus/consensus-engine.d.ts +81 -0
  24. package/dist/consensus/consensus-engine.js +237 -0
  25. package/dist/consensus/consensus-engine.js.map +1 -0
  26. package/dist/consensus/index.d.ts +2 -0
  27. package/dist/consensus/index.js +2 -0
  28. package/dist/consensus/index.js.map +1 -0
  29. package/dist/feedback/__tests__/feedback-engine.test.d.ts +1 -0
  30. package/dist/feedback/__tests__/feedback-engine.test.js +156 -0
  31. package/dist/feedback/__tests__/feedback-engine.test.js.map +1 -0
  32. package/dist/feedback/feedback-engine.d.ts +61 -0
  33. package/dist/feedback/feedback-engine.js +203 -0
  34. package/dist/feedback/feedback-engine.js.map +1 -0
  35. package/dist/feedback/index.d.ts +2 -0
  36. package/dist/feedback/index.js +2 -0
  37. package/dist/feedback/index.js.map +1 -0
  38. package/dist/index.d.ts +32 -0
  39. package/dist/index.js +27 -0
  40. package/dist/index.js.map +1 -1
  41. package/dist/knowledge-graph/__tests__/knowledge-graph.test.d.ts +1 -0
  42. package/dist/knowledge-graph/__tests__/knowledge-graph.test.js +215 -0
  43. package/dist/knowledge-graph/__tests__/knowledge-graph.test.js.map +1 -0
  44. package/dist/knowledge-graph/fact-extractor.d.ts +23 -0
  45. package/dist/knowledge-graph/fact-extractor.js +70 -0
  46. package/dist/knowledge-graph/fact-extractor.js.map +1 -0
  47. package/dist/knowledge-graph/graph-engine.d.ts +78 -0
  48. package/dist/knowledge-graph/graph-engine.js +276 -0
  49. package/dist/knowledge-graph/graph-engine.js.map +1 -0
  50. package/dist/knowledge-graph/index.d.ts +4 -0
  51. package/dist/knowledge-graph/index.js +3 -0
  52. package/dist/knowledge-graph/index.js.map +1 -0
  53. package/dist/proactive/__tests__/proactive-engine.test.d.ts +1 -0
  54. package/dist/proactive/__tests__/proactive-engine.test.js +183 -0
  55. package/dist/proactive/__tests__/proactive-engine.test.js.map +1 -0
  56. package/dist/proactive/index.d.ts +2 -0
  57. package/dist/proactive/index.js +2 -0
  58. package/dist/proactive/index.js.map +1 -0
  59. package/dist/proactive/proactive-engine.d.ts +86 -0
  60. package/dist/proactive/proactive-engine.js +252 -0
  61. package/dist/proactive/proactive-engine.js.map +1 -0
  62. package/dist/rag/__tests__/rag-engine.test.d.ts +1 -0
  63. package/dist/rag/__tests__/rag-engine.test.js +235 -0
  64. package/dist/rag/__tests__/rag-engine.test.js.map +1 -0
  65. package/dist/rag/index.d.ts +4 -0
  66. package/dist/rag/index.js +3 -0
  67. package/dist/rag/index.js.map +1 -0
  68. package/dist/rag/rag-engine.d.ts +98 -0
  69. package/dist/rag/rag-engine.js +310 -0
  70. package/dist/rag/rag-engine.js.map +1 -0
  71. package/dist/rag/rag-indexer.d.ts +52 -0
  72. package/dist/rag/rag-indexer.js +144 -0
  73. package/dist/rag/rag-indexer.js.map +1 -0
  74. package/dist/research/__tests__/autonomy-features.test.d.ts +1 -0
  75. package/dist/research/__tests__/autonomy-features.test.js +155 -0
  76. package/dist/research/__tests__/autonomy-features.test.js.map +1 -0
  77. package/dist/research/__tests__/semantic-compressor.test.d.ts +1 -0
  78. package/dist/research/__tests__/semantic-compressor.test.js +153 -0
  79. package/dist/research/__tests__/semantic-compressor.test.js.map +1 -0
  80. package/dist/research/semantic-compressor.d.ts +55 -0
  81. package/dist/research/semantic-compressor.js +227 -0
  82. package/dist/research/semantic-compressor.js.map +1 -0
  83. package/dist/teaching/__tests__/teaching.test.d.ts +1 -0
  84. package/dist/teaching/__tests__/teaching.test.js +151 -0
  85. package/dist/teaching/__tests__/teaching.test.js.map +1 -0
  86. package/dist/teaching/curriculum.d.ts +32 -0
  87. package/dist/teaching/curriculum.js +89 -0
  88. package/dist/teaching/curriculum.js.map +1 -0
  89. package/dist/teaching/index.d.ts +4 -0
  90. package/dist/teaching/index.js +3 -0
  91. package/dist/teaching/index.js.map +1 -0
  92. package/dist/teaching/teaching-protocol.d.ts +74 -0
  93. package/dist/teaching/teaching-protocol.js +164 -0
  94. package/dist/teaching/teaching-protocol.js.map +1 -0
  95. package/dist/tool-learning/__tests__/tool-learning.test.d.ts +1 -0
  96. package/dist/tool-learning/__tests__/tool-learning.test.js +187 -0
  97. package/dist/tool-learning/__tests__/tool-learning.test.js.map +1 -0
  98. package/dist/tool-learning/index.d.ts +4 -0
  99. package/dist/tool-learning/index.js +3 -0
  100. package/dist/tool-learning/index.js.map +1 -0
  101. package/dist/tool-learning/tool-patterns.d.ts +47 -0
  102. package/dist/tool-learning/tool-patterns.js +125 -0
  103. package/dist/tool-learning/tool-patterns.js.map +1 -0
  104. package/dist/tool-learning/tool-tracker.d.ts +58 -0
  105. package/dist/tool-learning/tool-tracker.js +135 -0
  106. package/dist/tool-learning/tool-tracker.js.map +1 -0
  107. package/dist/user-model/__tests__/user-model.test.d.ts +1 -0
  108. package/dist/user-model/__tests__/user-model.test.js +142 -0
  109. package/dist/user-model/__tests__/user-model.test.js.map +1 -0
  110. package/dist/user-model/adaptive-context.d.ts +18 -0
  111. package/dist/user-model/adaptive-context.js +46 -0
  112. package/dist/user-model/adaptive-context.js.map +1 -0
  113. package/dist/user-model/index.d.ts +4 -0
  114. package/dist/user-model/index.js +3 -0
  115. package/dist/user-model/index.js.map +1 -0
  116. package/dist/user-model/user-model.d.ts +53 -0
  117. package/dist/user-model/user-model.js +204 -0
  118. package/dist/user-model/user-model.js.map +1 -0
  119. package/package.json +1 -1
@@ -202,6 +202,8 @@ canvas{display:block;width:100%;height:100%}
202
202
  .btn{padding:6px 16px;border-radius:var(--radius-sm);border:1px solid var(--border);background:var(--bg-card);color:var(--text);cursor:pointer;font-size:12px;transition:all .2s}
203
203
  .btn:hover{border-color:var(--cyan);color:var(--cyan)}
204
204
  .btn.btn-active{border-color:var(--green);color:var(--green);background:rgba(0,255,136,0.08)}
205
+ .lang-btn{padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600;border:1px solid var(--border);background:rgba(100,140,255,0.04);color:var(--text-dim);cursor:pointer;transition:all .2s;letter-spacing:1px}
206
+ .lang-btn:hover{border-color:var(--cyan);color:var(--cyan)}
205
207
 
206
208
  /* ── Scrollbar ─────────────────────────────────────────── */
207
209
  ::-webkit-scrollbar{width:6px}
@@ -229,14 +231,14 @@ canvas{display:block;width:100%;height:100%}
229
231
  <div class="sidebar-brand">COMMAND CENTER<span>Brain Ecosystem</span></div>
230
232
  <div class="nav-section">Views</div>
231
233
  <div class="nav-item active" data-page="overview"><span class="nav-icon">&#x1F30D;</span><span class="nav-label">Ecosystem</span></div>
232
- <div class="nav-item" data-page="learning"><span class="nav-icon">&#x1F9E0;</span><span class="nav-label">Lern-Kreislauf</span></div>
234
+ <div class="nav-item" data-page="learning"><span class="nav-icon">&#x1F9E0;</span><span class="nav-label" data-t="Lern-Kreislauf">Lern-Kreislauf</span></div>
233
235
  <div class="nav-item" data-page="trading"><span class="nav-icon">&#x1F4C8;</span><span class="nav-label">Trading Flow</span></div>
234
236
  <div class="nav-item" data-page="marketing"><span class="nav-icon">&#x1F4E3;</span><span class="nav-label">Marketing Flow</span></div>
235
237
  <div class="nav-section">System</div>
236
238
  <div class="nav-item" data-page="crossbrain"><span class="nav-icon">&#x1F517;</span><span class="nav-label">Cross-Brain</span></div>
237
239
  <div class="nav-item" data-page="debates"><span class="nav-icon">&#x2696;</span><span class="nav-label">Debates</span></div>
238
- <div class="nav-item" data-page="activity"><span class="nav-icon">&#x26A1;</span><span class="nav-label">Aktivität</span></div>
239
- <div class="nav-item" data-page="infra"><span class="nav-icon">&#x2699;</span><span class="nav-label">Infrastruktur</span></div>
240
+ <div class="nav-item" data-page="activity"><span class="nav-icon">&#x26A1;</span><span class="nav-label" data-t="Aktivität">Aktivität</span></div>
241
+ <div class="nav-item" data-page="infra"><span class="nav-icon">&#x2699;</span><span class="nav-label" data-t="Infrastruktur">Infrastruktur</span></div>
240
242
  </div>
241
243
 
242
244
  <!-- ── Main ──────────────────────────────────────────── -->
@@ -250,6 +252,7 @@ canvas{display:block;width:100%;height:100%}
250
252
  </div>
251
253
  <span class="badge badge-off" id="healthBadge">--</span>
252
254
  <span class="badge badge-off" id="connectionBadge">Connecting...</span>
255
+ <button class="lang-btn" id="langToggle" onclick="setLang(currentLang==='en'?'de':'en')">EN</button>
253
256
  </div>
254
257
  </div>
255
258
 
@@ -258,11 +261,11 @@ canvas{display:block;width:100%;height:100%}
258
261
  <div class="page active" id="page-overview">
259
262
  <!-- Quick Actions -->
260
263
  <div class="section">
261
- <div class="section-title"><span class="icon">&#x1F3AE;</span> Schnellaktionen</div>
264
+ <div class="section-title"><span class="icon">&#x1F3AE;</span> <span data-t="Schnellaktionen">Schnellaktionen</span></div>
262
265
  <div class="quick-actions" id="quickActions">
263
- <button class="action-btn" data-action="learning-cycle"><span class="action-icon">&#x1F504;</span> Lernzyklus starten</button>
266
+ <button class="action-btn" data-action="learning-cycle"><span class="action-icon">&#x1F504;</span> <span data-t="Lernzyklus starten">Lernzyklus starten</span></button>
264
267
  <button class="action-btn" data-action="borg-sync"><span class="action-icon">&#x1F47E;</span> Borg Sync</button>
265
- <button class="action-btn" data-action="tech-scan"><span class="action-icon">&#x1F4E1;</span> Tech-Radar Scan</button>
268
+ <button class="action-btn" data-action="tech-scan"><span class="action-icon">&#x1F4E1;</span> <span data-t="Tech-Radar Scan">Tech-Radar Scan</span></button>
266
269
  <button class="action-btn" data-action="health-check"><span class="action-icon">&#x1F3E5;</span> Health Check</button>
267
270
  </div>
268
271
  </div>
@@ -288,13 +291,13 @@ canvas{display:block;width:100%;height:100%}
288
291
  </div>
289
292
  </div>
290
293
  <div class="section">
291
- <div class="section-title"><span class="icon">&#x1F4CA;</span> KI-Nutzung</div>
294
+ <div class="section-title"><span class="icon">&#x1F4CA;</span> <span data-t="KI-Nutzung">KI-Nutzung</span></div>
292
295
  <div class="card" id="llmCard"><div class="empty">Warte auf KI-Daten...</div></div>
293
296
  </div>
294
297
  </div>
295
298
 
296
299
  <div class="section">
297
- <div class="section-title"><span class="icon">&#x1F4AD;</span> Brain denkt gerade... <span id="thoughtCount" style="color:var(--text-dim);font-weight:400;font-size:12px"></span></div>
300
+ <div class="section-title"><span class="icon">&#x1F4AD;</span> <span data-t="Brain denkt gerade...">Brain denkt gerade...</span> <span id="thoughtCount" style="color:var(--text-dim);font-weight:400;font-size:12px"></span></div>
298
301
  <div class="card" style="padding:0">
299
302
  <div class="thought-stream" id="thoughtStream"><div class="empty">Warte auf Gedanken...</div></div>
300
303
  </div>
@@ -303,14 +306,14 @@ canvas{display:block;width:100%;height:100%}
303
306
 
304
307
  <!-- Error Log -->
305
308
  <div class="section">
306
- <div class="section-title"><span class="icon">&#x26A0;</span> Letzte Fehler & Warnungen <span id="errorCount" style="color:var(--text-dim);font-weight:400;font-size:12px"></span></div>
309
+ <div class="section-title"><span class="icon">&#x26A0;</span> <span data-t="Letzte Fehler & Warnungen">Letzte Fehler & Warnungen</span> <span id="errorCount" style="color:var(--text-dim);font-weight:400;font-size:12px"></span></div>
307
310
  <div class="card" style="padding:0">
308
311
  <div class="error-feed" id="errorFeed"><div class="empty">Keine Fehler — alles läuft!</div></div>
309
312
  </div>
310
313
  </div>
311
314
 
312
315
  <div class="section">
313
- <div class="section-title"><span class="icon">&#x1F310;</span> Peer Verbindungen</div>
316
+ <div class="section-title"><span class="icon">&#x1F310;</span> <span data-t="Peer Verbindungen">Peer Verbindungen</span></div>
314
317
  <div class="card canvas-wrap" style="height:180px">
315
318
  <canvas id="peerCanvas"></canvas>
316
319
  </div>
@@ -320,30 +323,30 @@ canvas{display:block;width:100%;height:100%}
320
323
  <!-- ════ Page 2: Lern-Kreislauf ═════════════════════ -->
321
324
  <div class="page" id="page-learning">
322
325
  <div class="section">
323
- <div class="section-title"><span class="icon">&#x1F504;</span> So lernt Brain — Der Kreislauf</div>
324
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Daten kommen rein, Brain analysiert sie, bildet Hypothesen, testet sie als Experimente und macht daraus Wissen. Dieser Kreislauf läuft ständig.</p>
326
+ <div class="section-title"><span class="icon">&#x1F504;</span> <span data-t="So lernt Brain — Der Kreislauf">So lernt Brain — Der Kreislauf</span></div>
327
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Daten kommen rein, Brain analysiert sie, bildet Hypothesen, testet sie als Experimente und macht daraus Wissen. Dieser Kreislauf läuft ständig.">Daten kommen rein, Brain analysiert sie, bildet Hypothesen, testet sie als Experimente und macht daraus Wissen. Dieser Kreislauf läuft ständig.</p>
325
328
  <div class="pipeline" id="learnPipeline">
326
- <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F4E5;</div><div class="pipe-label">Daten rein</div><div class="pipe-value" id="lp-data">0</div></div></div>
329
+ <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F4E5;</div><div class="pipe-label" data-t="Daten rein">Daten rein</div><div class="pipe-value" id="lp-data">0</div></div></div>
327
330
  <div class="pipe-arrow">&#x27A1;</div>
328
- <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F50D;</div><div class="pipe-label">Analysieren</div><div class="pipe-value" id="lp-analysis">0</div></div></div>
331
+ <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F50D;</div><div class="pipe-label" data-t="Analysieren">Analysieren</div><div class="pipe-value" id="lp-analysis">0</div></div></div>
329
332
  <div class="pipe-arrow">&#x27A1;</div>
330
- <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F4A1;</div><div class="pipe-label">Ideen bilden</div><div class="pipe-value" id="lp-hypotheses">0</div></div></div>
333
+ <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F4A1;</div><div class="pipe-label" data-t="Ideen bilden">Ideen bilden</div><div class="pipe-value" id="lp-hypotheses">0</div></div></div>
331
334
  <div class="pipe-arrow">&#x27A1;</div>
332
- <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F9EA;</div><div class="pipe-label">Ausprobieren</div><div class="pipe-value" id="lp-experiments">0</div></div></div>
335
+ <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F9EA;</div><div class="pipe-label" data-t="Ausprobieren">Ausprobieren</div><div class="pipe-value" id="lp-experiments">0</div></div></div>
333
336
  <div class="pipe-arrow">&#x27A1;</div>
334
- <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F4DC;</div><div class="pipe-label">Wissen merken</div><div class="pipe-value" id="lp-principles">0</div></div></div>
337
+ <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x1F4DC;</div><div class="pipe-label" data-t="Wissen merken">Wissen merken</div><div class="pipe-value" id="lp-principles">0</div></div></div>
335
338
  <div class="pipe-arrow">&#x27A1;</div>
336
- <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x26A1;</div><div class="pipe-label">Umsetzen</div><div class="pipe-value" id="lp-actions">0</div></div></div>
339
+ <div class="pipe-stage"><div class="pipe-box"><div class="pipe-icon">&#x26A1;</div><div class="pipe-label" data-t="Umsetzen">Umsetzen</div><div class="pipe-value" id="lp-actions">0</div></div></div>
337
340
  </div>
338
341
  </div>
339
342
 
340
343
  <!-- Engine Dependency Flow -->
341
344
  <div class="section">
342
- <div class="section-title"><span class="icon">&#x1F500;</span> Wie die Engines zusammenarbeiten</div>
343
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Jede Engine hat eine Aufgabe. Zusammen bilden sie eine Kette — von der Beobachtung bis zur Aktion.</p>
345
+ <div class="section-title"><span class="icon">&#x1F500;</span> <span data-t="Wie die Engines zusammenarbeiten">Wie die Engines zusammenarbeiten</span></div>
346
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Jede Engine hat eine Aufgabe. Zusammen bilden sie eine Kette — von der Beobachtung bis zur Aktion.">Jede Engine hat eine Aufgabe. Zusammen bilden sie eine Kette — von der Beobachtung bis zur Aktion.</p>
344
347
  <div class="dep-flow" id="engineDependencyFlow">
345
348
  <div class="dep-group">
346
- <div class="dep-group-title">&#x1F441; Beobachten</div>
349
+ <div class="dep-group-title">&#x1F441; <span data-t="Beobachten">Beobachten</span></div>
347
350
  <div class="dep-engine">DataScout</div>
348
351
  <div class="dep-engine">TechRadar</div>
349
352
  <div class="dep-engine">SignalScanner</div>
@@ -351,7 +354,7 @@ canvas{display:block;width:100%;height:100%}
351
354
  </div>
352
355
  <div class="dep-arrow">&#x27A1;</div>
353
356
  <div class="dep-group">
354
- <div class="dep-group-title">&#x1F9E0; Verstehen</div>
357
+ <div class="dep-group-title">&#x1F9E0; <span data-t="Verstehen">Verstehen</span></div>
355
358
  <div class="dep-engine">CausalEngine</div>
356
359
  <div class="dep-engine">PatternEngine</div>
357
360
  <div class="dep-engine">Curiosity</div>
@@ -359,28 +362,28 @@ canvas{display:block;width:100%;height:100%}
359
362
  </div>
360
363
  <div class="dep-arrow">&#x27A1;</div>
361
364
  <div class="dep-group">
362
- <div class="dep-group-title">&#x1F4A1; Ideen</div>
365
+ <div class="dep-group-title">&#x1F4A1; <span data-t="Ideen">Ideen</span></div>
363
366
  <div class="dep-engine">HypothesisEngine</div>
364
367
  <div class="dep-engine">DreamEngine</div>
365
368
  <div class="dep-engine">DebateEngine</div>
366
369
  </div>
367
370
  <div class="dep-arrow">&#x27A1;</div>
368
371
  <div class="dep-group">
369
- <div class="dep-group-title">&#x1F9EA; Testen</div>
372
+ <div class="dep-group-title">&#x1F9EA; <span data-t="Testen">Testen</span></div>
370
373
  <div class="dep-engine">ExperimentEngine</div>
371
374
  <div class="dep-engine">SimulationEngine</div>
372
375
  <div class="dep-engine">Prediction</div>
373
376
  </div>
374
377
  <div class="dep-arrow">&#x27A1;</div>
375
378
  <div class="dep-group">
376
- <div class="dep-group-title">&#x1F4DA; Wissen</div>
379
+ <div class="dep-group-title">&#x1F4DA; <span data-t="Wissen">Wissen</span></div>
377
380
  <div class="dep-engine">KnowledgeDistiller</div>
378
381
  <div class="dep-engine">MemoryPalace</div>
379
382
  <div class="dep-engine">ResearchJournal</div>
380
383
  </div>
381
384
  <div class="dep-arrow">&#x27A1;</div>
382
385
  <div class="dep-group">
383
- <div class="dep-group-title">&#x26A1; Handeln</div>
386
+ <div class="dep-group-title">&#x26A1; <span data-t="Handeln">Handeln</span></div>
384
387
  <div class="dep-engine">SelfMod</div>
385
388
  <div class="dep-engine">GoalEngine</div>
386
389
  <div class="dep-engine">Strategy</div>
@@ -391,27 +394,27 @@ canvas{display:block;width:100%;height:100%}
391
394
 
392
395
  <!-- Knowledge Growth -->
393
396
  <div class="section">
394
- <div class="section-title"><span class="icon">&#x1F4C8;</span> Wissens-Wachstum — Wird Brain schlauer?</div>
397
+ <div class="section-title"><span class="icon">&#x1F4C8;</span> <span data-t="Wissens-Wachstum — Wird Brain schlauer?">Wissens-Wachstum — Wird Brain schlauer?</span></div>
395
398
  <div class="card">
396
399
  <div class="grid grid-4" id="knowledgeTotals">
397
- <div style="text-align:center"><div class="card-value" id="kn-principles" style="color:var(--cyan)">0</div><div class="card-sub">Regeln gelernt</div></div>
398
- <div style="text-align:center"><div class="card-value" id="kn-hypotheses" style="color:var(--yellow)">0</div><div class="card-sub">Hypothesen getestet</div></div>
399
- <div style="text-align:center"><div class="card-value" id="kn-experiments" style="color:var(--green)">0</div><div class="card-sub">Experimente gemacht</div></div>
400
- <div style="text-align:center"><div class="card-value" id="kn-errors" style="color:var(--red)">0</div><div class="card-sub">Fehler gelöst</div></div>
400
+ <div style="text-align:center"><div class="card-value" id="kn-principles" style="color:var(--cyan)">0</div><div class="card-sub" data-t="Regeln gelernt">Regeln gelernt</div></div>
401
+ <div style="text-align:center"><div class="card-value" id="kn-hypotheses" style="color:var(--yellow)">0</div><div class="card-sub" data-t="Hypothesen getestet">Hypothesen getestet</div></div>
402
+ <div style="text-align:center"><div class="card-value" id="kn-experiments" style="color:var(--green)">0</div><div class="card-sub" data-t="Experimente gemacht">Experimente gemacht</div></div>
403
+ <div style="text-align:center"><div class="card-value" id="kn-errors" style="color:var(--red)">0</div><div class="card-sub" data-t="Fehler gelöst">Fehler gelöst</div></div>
401
404
  </div>
402
405
  <div class="chart-wrap" id="knowledgeChart">
403
406
  <svg id="knowledgeSvg" viewBox="0 0 600 180" preserveAspectRatio="none"></svg>
404
407
  </div>
405
408
  <div style="display:flex;gap:16px;justify-content:center;font-size:10px;color:var(--text-dim)">
406
- <span><span style="color:var(--cyan)">&#x2B24;</span> Regeln</span>
407
- <span><span style="color:var(--green)">&#x2B24;</span> Lösungen</span>
408
- <span><span style="color:var(--red)">&#x2B24;</span> Fehler</span>
409
+ <span><span style="color:var(--cyan)">&#x2B24;</span> <span data-t="Regeln">Regeln</span></span>
410
+ <span><span style="color:var(--green)">&#x2B24;</span> <span data-t="Lösungen">Lösungen</span></span>
411
+ <span><span style="color:var(--red)">&#x2B24;</span> <span data-t="Fehler">Fehler</span></span>
409
412
  </div>
410
413
  </div>
411
414
  </div>
412
415
 
413
416
  <div class="section">
414
- <div class="section-title"><span class="icon">&#x1F3ED;</span> Engine Stationen</div>
417
+ <div class="section-title"><span class="icon">&#x1F3ED;</span> <span data-t="Engine Stationen">Engine Stationen</span></div>
415
418
  <div class="engine-grid" id="brainEngineGrid"><div class="empty">Loading...</div></div>
416
419
  </div>
417
420
  </div>
@@ -419,24 +422,24 @@ canvas{display:block;width:100%;height:100%}
419
422
  <!-- ════ Page 3: Trading Flow ═══════════════════════ -->
420
423
  <div class="page" id="page-trading">
421
424
  <div class="section">
422
- <div class="section-title"><span class="icon">&#x1F4C8;</span> So tradet Trading-Brain</div>
423
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Signale kommen rein, werden analysiert, als Paper Trade getestet und das Ergebnis fließt zurück ins Lernen.</p>
425
+ <div class="section-title"><span class="icon">&#x1F4C8;</span> <span data-t="So tradet Trading-Brain">So tradet Trading-Brain</span></div>
426
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Signale kommen rein, werden analysiert, als Paper Trade getestet und das Ergebnis fließt zurück ins Lernen.">Signale kommen rein, werden analysiert, als Paper Trade getestet und das Ergebnis fließt zurück ins Lernen.</p>
424
427
  <div class="pipeline">
425
- <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(0,255,136,0.2)"><div class="pipe-icon">&#x1F4E1;</div><div class="pipe-label">Signale</div><div class="pipe-value" id="tp-signals" style="color:var(--green)">0</div></div></div>
428
+ <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(0,255,136,0.2)"><div class="pipe-icon">&#x1F4E1;</div><div class="pipe-label" data-t="Signale">Signale</div><div class="pipe-value" id="tp-signals" style="color:var(--green)">0</div></div></div>
426
429
  <div class="pipe-arrow" style="color:var(--green)">&#x27A1;</div>
427
- <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(0,255,136,0.2)"><div class="pipe-icon">&#x1F50E;</div><div class="pipe-label">Analyse</div><div class="pipe-value" id="tp-analysis" style="color:var(--green)">0</div></div></div>
430
+ <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(0,255,136,0.2)"><div class="pipe-icon">&#x1F50E;</div><div class="pipe-label" data-t="Analyse">Analyse</div><div class="pipe-value" id="tp-analysis" style="color:var(--green)">0</div></div></div>
428
431
  <div class="pipe-arrow" style="color:var(--green)">&#x27A1;</div>
429
432
  <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(0,255,136,0.2)"><div class="pipe-icon">&#x1F4B5;</div><div class="pipe-label">Paper Trade</div><div class="pipe-value" id="tp-trades" style="color:var(--green)">0</div></div></div>
430
433
  <div class="pipe-arrow" style="color:var(--green)">&#x27A1;</div>
431
- <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(0,255,136,0.2)"><div class="pipe-icon">&#x1F4CA;</div><div class="pipe-label">Ergebnis</div><div class="pipe-value" id="tp-pnl" style="color:var(--green)">$0</div></div></div>
434
+ <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(0,255,136,0.2)"><div class="pipe-icon">&#x1F4CA;</div><div class="pipe-label" data-t="Ergebnis">Ergebnis</div><div class="pipe-value" id="tp-pnl" style="color:var(--green)">$0</div></div></div>
432
435
  <div class="pipe-arrow" style="color:var(--green)">&#x27A1;</div>
433
- <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(0,255,136,0.2)"><div class="pipe-icon">&#x1F393;</div><div class="pipe-label">Lernen</div><div class="pipe-value" id="tp-learned" style="color:var(--green)">0</div></div></div>
436
+ <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(0,255,136,0.2)"><div class="pipe-icon">&#x1F393;</div><div class="pipe-label" data-t="Lernen">Lernen</div><div class="pipe-value" id="tp-learned" style="color:var(--green)">0</div></div></div>
434
437
  </div>
435
438
  </div>
436
439
  <div class="grid grid-3">
437
- <div class="card"><div class="card-title">Equity</div><div class="card-value" id="tradingEquity" style="color:var(--green)">--</div><div class="card-sub">Paper Trading Guthaben</div></div>
438
- <div class="card"><div class="card-title">Win Rate</div><div class="card-value" id="tradingWinRate" style="color:var(--green)">--</div><div class="card-sub">Gewinnrate aller Trades</div></div>
439
- <div class="card"><div class="card-title">Offene Positionen</div><div class="card-value" id="tradingPositions" style="color:var(--green)">--</div><div class="card-sub">Aktive Trades gerade</div></div>
440
+ <div class="card"><div class="card-title">Equity</div><div class="card-value" id="tradingEquity" style="color:var(--green)">--</div><div class="card-sub" data-t="Paper Trading Guthaben">Paper Trading Guthaben</div></div>
441
+ <div class="card"><div class="card-title">Win Rate</div><div class="card-value" id="tradingWinRate" style="color:var(--green)">--</div><div class="card-sub" data-t="Gewinnrate aller Trades">Gewinnrate aller Trades</div></div>
442
+ <div class="card"><div class="card-title" data-t="Offene Positionen">Offene Positionen</div><div class="card-value" id="tradingPositions" style="color:var(--green)">--</div><div class="card-sub" data-t="Aktive Trades gerade">Aktive Trades gerade</div></div>
440
443
  </div>
441
444
  <div class="section" style="margin-top:16px">
442
445
  <div class="section-title"><span class="icon">&#x1F3ED;</span> Trading Engines</div>
@@ -447,22 +450,22 @@ canvas{display:block;width:100%;height:100%}
447
450
  <!-- ════ Page 4: Marketing Flow ═════════════════════ -->
448
451
  <div class="page" id="page-marketing">
449
452
  <div class="section">
450
- <div class="section-title"><span class="icon">&#x1F4E3;</span> So lernt Marketing-Brain</div>
451
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Posts werden veröffentlicht, das Engagement wird gemessen, Muster erkannt und die Strategie angepasst.</p>
453
+ <div class="section-title"><span class="icon">&#x1F4E3;</span> <span data-t="So lernt Marketing-Brain">So lernt Marketing-Brain</span></div>
454
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Posts werden veröffentlicht, das Engagement wird gemessen, Muster erkannt und die Strategie angepasst.">Posts werden veröffentlicht, das Engagement wird gemessen, Muster erkannt und die Strategie angepasst.</p>
452
455
  <div class="pipeline">
453
456
  <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(255,68,204,0.2)"><div class="pipe-icon">&#x270D;</div><div class="pipe-label">Posts</div><div class="pipe-value" id="mp-posts" style="color:var(--magenta)">0</div></div></div>
454
457
  <div class="pipe-arrow" style="color:var(--magenta)">&#x27A1;</div>
455
458
  <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(255,68,204,0.2)"><div class="pipe-icon">&#x1F4CA;</div><div class="pipe-label">Engagement</div><div class="pipe-value" id="mp-engagement" style="color:var(--magenta)">0</div></div></div>
456
459
  <div class="pipe-arrow" style="color:var(--magenta)">&#x27A1;</div>
457
- <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(255,68,204,0.2)"><div class="pipe-icon">&#x1F50D;</div><div class="pipe-label">Muster</div><div class="pipe-value" id="mp-patterns" style="color:var(--magenta)">0</div></div></div>
460
+ <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(255,68,204,0.2)"><div class="pipe-icon">&#x1F50D;</div><div class="pipe-label" data-t="Muster">Muster</div><div class="pipe-value" id="mp-patterns" style="color:var(--magenta)">0</div></div></div>
458
461
  <div class="pipe-arrow" style="color:var(--magenta)">&#x27A1;</div>
459
- <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(255,68,204,0.2)"><div class="pipe-icon">&#x1F3AF;</div><div class="pipe-label">Strategie</div><div class="pipe-value" id="mp-campaigns" style="color:var(--magenta)">0</div></div></div>
462
+ <div class="pipe-stage"><div class="pipe-box" style="border-color:rgba(255,68,204,0.2)"><div class="pipe-icon">&#x1F3AF;</div><div class="pipe-label" data-t="Strategie">Strategie</div><div class="pipe-value" id="mp-campaigns" style="color:var(--magenta)">0</div></div></div>
460
463
  </div>
461
464
  </div>
462
465
  <div class="grid grid-3">
463
- <div class="card"><div class="card-title">Top Content</div><div class="card-value" id="marketingTopContent" style="color:var(--magenta)">--</div><div class="card-sub">Bester Post</div></div>
464
- <div class="card"><div class="card-title">Kampagnen</div><div class="card-value" id="marketingCampaigns" style="color:var(--magenta)">--</div><div class="card-sub">Aktive Kampagnen</div></div>
465
- <div class="card"><div class="card-title">Audience</div><div class="card-value" id="marketingAudience" style="color:var(--magenta)">--</div><div class="card-sub">Zielgruppe</div></div>
466
+ <div class="card"><div class="card-title">Top Content</div><div class="card-value" id="marketingTopContent" style="color:var(--magenta)">--</div><div class="card-sub" data-t="Bester Post">Bester Post</div></div>
467
+ <div class="card"><div class="card-title" data-t="Kampagnen">Kampagnen</div><div class="card-value" id="marketingCampaigns" style="color:var(--magenta)">--</div><div class="card-sub" data-t="Aktive Kampagnen">Aktive Kampagnen</div></div>
468
+ <div class="card"><div class="card-title">Audience</div><div class="card-value" id="marketingAudience" style="color:var(--magenta)">--</div><div class="card-sub" data-t="Zielgruppe">Zielgruppe</div></div>
466
469
  </div>
467
470
  <div class="section" style="margin-top:16px">
468
471
  <div class="section-title"><span class="icon">&#x1F3ED;</span> Marketing Engines</div>
@@ -473,17 +476,17 @@ canvas{display:block;width:100%;height:100%}
473
476
  <!-- ════ Page 5: Cross-Brain & Borg ═════════════════ -->
474
477
  <div class="page" id="page-crossbrain">
475
478
  <div class="section">
476
- <div class="section-title"><span class="icon">&#x1F517;</span> So kommunizieren die Brains</div>
477
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Die drei Brains tauschen ständig Nachrichten aus. Jeder fliegende Punkt ist eine Nachricht. Lila = Borg-Wissens-Sync.</p>
479
+ <div class="section-title"><span class="icon">&#x1F517;</span> <span data-t="So kommunizieren die Brains">So kommunizieren die Brains</span></div>
480
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Die drei Brains tauschen ständig Nachrichten aus. Jeder fliegende Punkt ist eine Nachricht. Lila = Borg-Wissens-Sync.">Die drei Brains tauschen ständig Nachrichten aus. Jeder fliegende Punkt ist eine Nachricht. Lila = Borg-Wissens-Sync.</p>
478
481
  <div class="card canvas-wrap" style="height:280px">
479
482
  <canvas id="crossBrainCanvas"></canvas>
480
483
  </div>
481
484
  </div>
482
485
  <div class="grid grid-2">
483
486
  <div class="section">
484
- <div class="section-title"><span class="icon">&#x1F47E;</span> Borg Sync — Geteiltes Wissen</div>
487
+ <div class="section-title"><span class="icon">&#x1F47E;</span> <span data-t="Borg Sync — Geteiltes Wissen">Borg Sync — Geteiltes Wissen</span></div>
485
488
  <div class="card" id="borgCard">
486
- <p style="font-size:11px;color:var(--text-dim);margin-bottom:10px">Borg synchronisiert Wissen zwischen allen Brains. Was einer lernt, wissen alle.</p>
489
+ <p style="font-size:11px;color:var(--text-dim);margin-bottom:10px" data-t="Borg synchronisiert Wissen zwischen allen Brains. Was einer lernt, wissen alle.">Borg synchronisiert Wissen zwischen allen Brains. Was einer lernt, wissen alle.</p>
487
490
  <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
488
491
  <div>
489
492
  <div class="card-title" style="margin-bottom:4px">Collective Sync</div>
@@ -495,12 +498,12 @@ canvas{display:block;width:100%;height:100%}
495
498
  </div>
496
499
  </div>
497
500
  <div class="section">
498
- <div class="section-title"><span class="icon">&#x1F4DC;</span> Korrelationen — Was hängt zusammen?</div>
501
+ <div class="section-title"><span class="icon">&#x1F4DC;</span> <span data-t="Korrelationen — Was hängt zusammen?">Korrelationen — Was hängt zusammen?</span></div>
499
502
  <div class="card"><div id="correlationList"><div class="empty">Noch keine Korrelationen gefunden</div></div></div>
500
503
  </div>
501
504
  </div>
502
505
  <div class="section">
503
- <div class="section-title"><span class="icon">&#x1F4C3;</span> Sync Verlauf</div>
506
+ <div class="section-title"><span class="icon">&#x1F4C3;</span> <span data-t="Sync Verlauf">Sync Verlauf</span></div>
504
507
  <div class="card"><div id="borgHistory"><div class="empty">Noch kein Sync passiert</div></div></div>
505
508
  </div>
506
509
  </div>
@@ -509,13 +512,13 @@ canvas{display:block;width:100%;height:100%}
509
512
  <div class="page" id="page-activity">
510
513
  <!-- Self-Modification -->
511
514
  <div class="section">
512
- <div class="section-title"><span class="icon">&#x1F527;</span> Brain verbessert sich selbst</div>
513
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Brain erkennt Probleme im eigenen Code und schlägt Verbesserungen vor. Jede Änderung wird erst getestet, bevor sie angewendet wird.</p>
515
+ <div class="section-title"><span class="icon">&#x1F527;</span> <span data-t="Brain verbessert sich selbst">Brain verbessert sich selbst</span></div>
516
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Brain erkennt Probleme im eigenen Code und schlägt Verbesserungen vor. Jede Änderung wird erst getestet, bevor sie angewendet wird.">Brain erkennt Probleme im eigenen Code und schlägt Verbesserungen vor. Jede Änderung wird erst getestet, bevor sie angewendet wird.</p>
514
517
  <div class="grid grid-4" id="selfModStats">
515
- <div class="card" style="text-align:center"><div class="card-value" id="sm-total" style="color:var(--cyan)">0</div><div class="card-sub">Vorschläge insgesamt</div></div>
516
- <div class="card" style="text-align:center"><div class="card-value" id="sm-applied" style="color:var(--green)">0</div><div class="card-sub">Erfolgreich angewendet</div></div>
517
- <div class="card" style="text-align:center"><div class="card-value" id="sm-testing" style="color:var(--yellow)">0</div><div class="card-sub">Wird gerade getestet</div></div>
518
- <div class="card" style="text-align:center"><div class="card-value" id="sm-failed" style="color:var(--red)">0</div><div class="card-sub">Fehlgeschlagen</div></div>
518
+ <div class="card" style="text-align:center"><div class="card-value" id="sm-total" style="color:var(--cyan)">0</div><div class="card-sub" data-t="Vorschläge insgesamt">Vorschläge insgesamt</div></div>
519
+ <div class="card" style="text-align:center"><div class="card-value" id="sm-applied" style="color:var(--green)">0</div><div class="card-sub" data-t="Erfolgreich angewendet">Erfolgreich angewendet</div></div>
520
+ <div class="card" style="text-align:center"><div class="card-value" id="sm-testing" style="color:var(--yellow)">0</div><div class="card-sub" data-t="Wird gerade getestet">Wird gerade getestet</div></div>
521
+ <div class="card" style="text-align:center"><div class="card-value" id="sm-failed" style="color:var(--red)">0</div><div class="card-sub" data-t="Fehlgeschlagen">Fehlgeschlagen</div></div>
519
522
  </div>
520
523
  <div class="card" style="padding:0;margin-top:12px">
521
524
  <div style="max-height:300px;overflow-y:auto" id="selfModFeed"><div class="empty">Brain hat sich noch nicht selbst verbessert</div></div>
@@ -524,12 +527,12 @@ canvas{display:block;width:100%;height:100%}
524
527
 
525
528
  <!-- Mission Tracker -->
526
529
  <div class="section">
527
- <div class="section-title"><span class="icon">&#x1F680;</span> Aktive Recherche-Missionen</div>
528
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Brain forscht eigenständig zu Themen. Jede Mission durchläuft 5 Phasen: Aufteilen, Sammeln, Hypothesen bilden, Analysieren, Zusammenfassen.</p>
530
+ <div class="section-title"><span class="icon">&#x1F680;</span> <span data-t="Aktive Recherche-Missionen">Aktive Recherche-Missionen</span></div>
531
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Brain forscht eigenständig zu Themen. Jede Mission durchläuft 5 Phasen: Aufteilen, Sammeln, Hypothesen bilden, Analysieren, Zusammenfassen.">Brain forscht eigenständig zu Themen. Jede Mission durchläuft 5 Phasen: Aufteilen, Sammeln, Hypothesen bilden, Analysieren, Zusammenfassen.</p>
529
532
  <div class="grid grid-3" id="missionStats">
530
- <div class="card" style="text-align:center"><div class="card-value" id="ms-active" style="color:var(--cyan)">0</div><div class="card-sub">Aktive Missionen</div></div>
531
- <div class="card" style="text-align:center"><div class="card-value" id="ms-completed" style="color:var(--green)">0</div><div class="card-sub">Abgeschlossen</div></div>
532
- <div class="card" style="text-align:center"><div class="card-value" id="ms-sources" style="color:var(--purple)">0</div><div class="card-sub">Quellen gesammelt</div></div>
533
+ <div class="card" style="text-align:center"><div class="card-value" id="ms-active" style="color:var(--cyan)">0</div><div class="card-sub" data-t="Aktive Missionen">Aktive Missionen</div></div>
534
+ <div class="card" style="text-align:center"><div class="card-value" id="ms-completed" style="color:var(--green)">0</div><div class="card-sub" data-t="Abgeschlossen">Abgeschlossen</div></div>
535
+ <div class="card" style="text-align:center"><div class="card-value" id="ms-sources" style="color:var(--purple)">0</div><div class="card-sub" data-t="Quellen gesammelt">Quellen gesammelt</div></div>
533
536
  </div>
534
537
  <div id="missionList" style="margin-top:12px"><div class="empty">Keine aktiven Missionen</div></div>
535
538
  </div>
@@ -540,32 +543,32 @@ canvas{display:block;width:100%;height:100%}
540
543
  <!-- Debate Engine Status -->
541
544
  <div class="section">
542
545
  <div class="section-title"><span class="icon">&#x2696;</span> Debate Engine</div>
543
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Multi-Perspektiven-Debatten zu Schlüsselfragen. Jeder Brain liefert seine Sichtweise basierend auf Prinzipien, Hypothesen und Vorhersagen.</p>
546
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Multi-Perspektiven-Debatten zu Schlüsselfragen. Jeder Brain liefert seine Sichtweise basierend auf Prinzipien, Hypothesen und Vorhersagen.">Multi-Perspektiven-Debatten zu Schlüsselfragen. Jeder Brain liefert seine Sichtweise basierend auf Prinzipien, Hypothesen und Vorhersagen.</p>
544
547
  <div class="grid grid-4" id="debateStats">
545
- <div class="card" style="text-align:center"><div class="card-value" id="db-total" style="color:var(--cyan)">0</div><div class="card-sub">Debatten gesamt</div></div>
546
- <div class="card" style="text-align:center"><div class="card-value" id="db-open" style="color:var(--yellow)">0</div><div class="card-sub">Offen</div></div>
547
- <div class="card" style="text-align:center"><div class="card-value" id="db-synthesized" style="color:var(--green)">0</div><div class="card-sub">Synthesiert</div></div>
548
+ <div class="card" style="text-align:center"><div class="card-value" id="db-total" style="color:var(--cyan)">0</div><div class="card-sub" data-t="Debatten gesamt">Debatten gesamt</div></div>
549
+ <div class="card" style="text-align:center"><div class="card-value" id="db-open" style="color:var(--yellow)">0</div><div class="card-sub" data-t="Offen">Offen</div></div>
550
+ <div class="card" style="text-align:center"><div class="card-value" id="db-synthesized" style="color:var(--green)">0</div><div class="card-sub" data-t="Synthesiert">Synthesiert</div></div>
548
551
  <div class="card" style="text-align:center"><div class="card-value" id="db-challenges" style="color:var(--red)">0</div><div class="card-sub">Challenges</div></div>
549
552
  </div>
550
553
  </div>
551
554
 
552
555
  <!-- Recent Debates -->
553
556
  <div class="section">
554
- <div class="section-title"><span class="icon">&#x1F4AC;</span> Letzte Debatten</div>
557
+ <div class="section-title"><span class="icon">&#x1F4AC;</span> <span data-t="Letzte Debatten">Letzte Debatten</span></div>
555
558
  <div id="debateList" style="margin-top:8px"><div class="empty">Noch keine Debatten gestartet</div></div>
556
559
  </div>
557
560
 
558
561
  <!-- Advocatus Diaboli: Principle Challenges -->
559
562
  <div class="section">
560
- <div class="section-title"><span class="icon">&#x1F525;</span> Advocatus Diaboli — Prinzip-Challenges</div>
561
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Jedes Prinzip wird aktiv hinterfragt. Überlebt es die Gegenargumente, oder wird es geschwächt/widerlegt?</p>
563
+ <div class="section-title"><span class="icon">&#x1F525;</span> <span data-t="Advocatus Diaboli — Prinzip-Challenges">Advocatus Diaboli — Prinzip-Challenges</span></div>
564
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Jedes Prinzip wird aktiv hinterfragt. Überlebt es die Gegenargumente, oder wird es geschwächt/widerlegt?">Jedes Prinzip wird aktiv hinterfragt. Überlebt es die Gegenargumente, oder wird es geschwächt/widerlegt?</p>
562
565
  <div id="challengeList" style="margin-top:8px"><div class="empty">Noch keine Challenges durchgeführt</div></div>
563
566
  </div>
564
567
 
565
568
  <!-- Most Vulnerable Principles -->
566
569
  <div class="section">
567
- <div class="section-title"><span class="icon">&#x26A0;</span> Verwundbarste Prinzipien</div>
568
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Prinzipien mit den niedrigsten Resilienz-Scores — die schwächsten Überzeugungen, die überprüft werden sollten.</p>
570
+ <div class="section-title"><span class="icon">&#x26A0;</span> <span data-t="Verwundbarste Prinzipien">Verwundbarste Prinzipien</span></div>
571
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Prinzipien mit den niedrigsten Resilienz-Scores — die schwächsten Überzeugungen, die überprüft werden sollten.">Prinzipien mit den niedrigsten Resilienz-Scores — die schwächsten Überzeugungen, die überprüft werden sollten.</p>
569
572
  <div id="vulnerableList" style="margin-top:8px"><div class="empty">Keine verwundbaren Prinzipien</div></div>
570
573
  </div>
571
574
  </div>
@@ -573,8 +576,8 @@ canvas{display:block;width:100%;height:100%}
573
576
  <!-- ════ Page 8: Infrastruktur ══════════════════════ -->
574
577
  <div class="page" id="page-infra">
575
578
  <div class="section">
576
- <div class="section-title"><span class="icon">&#x1F6E1;</span> Watchdog — Daemon-Überwachung</div>
577
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px">Überwacht alle Brain-Daemons. Grün = gesund, Gelb = läuft aber Healthcheck fehlgeschlagen, Rot = gestoppt. Auto-Update alle 30s.</p>
579
+ <div class="section-title"><span class="icon">&#x1F6E1;</span> <span data-t="Watchdog — Daemon-Überwachung">Watchdog — Daemon-Überwachung</span></div>
580
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:12px" data-t="Überwacht alle Brain-Daemons. Grün = gesund, Gelb = läuft aber Healthcheck fehlgeschlagen, Rot = gestoppt. Auto-Update alle 30s.">Überwacht alle Brain-Daemons. Grün = gesund, Gelb = läuft aber Healthcheck fehlgeschlagen, Rot = gestoppt. Auto-Update alle 30s.</p>
578
581
  <div class="grid grid-3" id="watchdogCards"><div class="empty">Loading...</div></div>
579
582
  </div>
580
583
  <div class="section">
@@ -583,17 +586,17 @@ canvas{display:block;width:100%;height:100%}
583
586
  </div>
584
587
  <div class="grid grid-2">
585
588
  <div class="section">
586
- <div class="section-title"><span class="icon">&#x1F9E9;</span> Plugins — Erweiterungen</div>
589
+ <div class="section-title"><span class="icon">&#x1F9E9;</span> <span data-t="Plugins — Erweiterungen">Plugins — Erweiterungen</span></div>
587
590
  <div class="card" id="pluginCard"><div class="empty">Loading...</div></div>
588
591
  </div>
589
592
  <div class="section" style="min-height:100px">
590
- <div class="section-title"><span class="icon">&#x1F4CA;</span> Dienst-Statistik</div>
593
+ <div class="section-title"><span class="icon">&#x1F4CA;</span> <span data-t="Dienst-Statistik">Dienst-Statistik</span></div>
591
594
  <div class="card" id="watchdogStatsCard"><div class="empty">Loading...</div></div>
592
595
  </div>
593
596
  </div>
594
597
  <div class="section">
595
- <div class="section-title"><span class="icon">&#x1F3ED;</span> Alle Engines auf einen Blick</div>
596
- <p style="font-size:12px;color:var(--text-dim);margin-bottom:8px">Grün = aktiv, Gelb = bereit, Grau = aus. Die Zahl zeigt wie viele Gedanken die Engine produziert hat.</p>
598
+ <div class="section-title"><span class="icon">&#x1F3ED;</span> <span data-t="Alle Engines auf einen Blick">Alle Engines auf einen Blick</span></div>
599
+ <p style="font-size:12px;color:var(--text-dim);margin-bottom:8px" data-t="Grün = aktiv, Gelb = bereit, Grau = aus. Die Zahl zeigt wie viele Gedanken die Engine produziert hat.">Grün = aktiv, Gelb = bereit, Grau = aus. Die Zahl zeigt wie viele Gedanken die Engine produziert hat.</p>
597
600
  <div class="engine-grid" id="allEngineGrid"><div class="empty">Loading...</div></div>
598
601
  </div>
599
602
  </div>
@@ -609,7 +612,108 @@ const state = {
609
612
  errors:null, selfmod:null, missions:null, knowledge:null, debates:null
610
613
  };
611
614
 
615
+ // ── i18n ──────────────────────────────────────────────────
616
+ const translations = { en: {
617
+ 'Lern-Kreislauf':'Learning Cycle','Aktivität':'Activity','Infrastruktur':'Infrastructure',
618
+ 'Schnellaktionen':'Quick Actions','Lernzyklus starten':'Start Learning Cycle','Tech-Radar Scan':'Tech Radar Scan',
619
+ 'KI-Nutzung':'AI Usage','Brain denkt gerade...':'Brain is thinking...','Letzte Fehler & Warnungen':'Recent Errors & Warnings',
620
+ 'Peer Verbindungen':'Peer Connections','So lernt Brain — Der Kreislauf':'How Brain Learns — The Cycle',
621
+ 'Daten kommen rein, Brain analysiert sie, bildet Hypothesen, testet sie als Experimente und macht daraus Wissen. Dieser Kreislauf läuft ständig.':'Data comes in, Brain analyzes it, forms hypotheses, tests them as experiments, and turns them into knowledge. This cycle runs continuously.',
622
+ 'Daten rein':'Data In','Analysieren':'Analyze','Ideen bilden':'Form Ideas','Ausprobieren':'Experiment','Wissen merken':'Store Knowledge','Umsetzen':'Execute',
623
+ 'Wie die Engines zusammenarbeiten':'How Engines Work Together',
624
+ 'Jede Engine hat eine Aufgabe. Zusammen bilden sie eine Kette — von der Beobachtung bis zur Aktion.':'Each engine has a job. Together they form a chain — from observation to action.',
625
+ 'Beobachten':'Observe','Verstehen':'Understand','Ideen':'Ideas','Testen':'Test','Wissen':'Knowledge','Handeln':'Act',
626
+ 'Wissens-Wachstum — Wird Brain schlauer?':'Knowledge Growth — Is Brain Getting Smarter?',
627
+ 'Regeln gelernt':'Rules Learned','Hypothesen getestet':'Hypotheses Tested','Experimente gemacht':'Experiments Run','Fehler gelöst':'Errors Solved',
628
+ 'Regeln':'Rules','Lösungen':'Solutions','Fehler':'Errors','Engine Stationen':'Engine Stations',
629
+ 'So tradet Trading-Brain':'How Trading Brain Trades',
630
+ 'Signale kommen rein, werden analysiert, als Paper Trade getestet und das Ergebnis fließt zurück ins Lernen.':'Signals come in, get analyzed, tested as paper trades, and results feed back into learning.',
631
+ 'Signale':'Signals','Analyse':'Analysis','Ergebnis':'Result','Lernen':'Learn',
632
+ 'Paper Trading Guthaben':'Paper Trading Balance','Gewinnrate aller Trades':'Win Rate All Trades','Offene Positionen':'Open Positions','Aktive Trades gerade':'Active Trades Now',
633
+ 'So lernt Marketing-Brain':'How Marketing Brain Learns',
634
+ 'Posts werden veröffentlicht, das Engagement wird gemessen, Muster erkannt und die Strategie angepasst.':'Posts are published, engagement is measured, patterns detected, and strategy adjusted.',
635
+ 'Muster':'Patterns','Strategie':'Strategy','Bester Post':'Best Post','Kampagnen':'Campaigns','Aktive Kampagnen':'Active Campaigns','Zielgruppe':'Audience',
636
+ 'So kommunizieren die Brains':'How the Brains Communicate',
637
+ 'Die drei Brains tauschen ständig Nachrichten aus. Jeder fliegende Punkt ist eine Nachricht. Lila = Borg-Wissens-Sync.':'The three brains constantly exchange messages. Each flying dot is a message. Purple = Borg knowledge sync.',
638
+ 'Borg Sync — Geteiltes Wissen':'Borg Sync — Shared Knowledge',
639
+ 'Borg synchronisiert Wissen zwischen allen Brains. Was einer lernt, wissen alle.':'Borg synchronizes knowledge between all brains. What one learns, all know.',
640
+ 'Korrelationen — Was hängt zusammen?':'Correlations — What\'s Connected?','Sync Verlauf':'Sync History',
641
+ 'Brain verbessert sich selbst':'Brain Improves Itself',
642
+ 'Brain erkennt Probleme im eigenen Code und schlägt Verbesserungen vor. Jede Änderung wird erst getestet, bevor sie angewendet wird.':'Brain detects issues in its own code and suggests improvements. Each change is tested before being applied.',
643
+ 'Vorschläge insgesamt':'Total Proposals','Erfolgreich angewendet':'Successfully Applied','Wird gerade getestet':'Currently Testing','Fehlgeschlagen':'Failed',
644
+ 'Aktive Recherche-Missionen':'Active Research Missions',
645
+ 'Brain forscht eigenständig zu Themen. Jede Mission durchläuft 5 Phasen: Aufteilen, Sammeln, Hypothesen bilden, Analysieren, Zusammenfassen.':'Brain researches topics autonomously. Each mission goes through 5 phases: decompose, gather, hypothesize, analyze, synthesize.',
646
+ 'Aktive Missionen':'Active Missions','Abgeschlossen':'Completed','Quellen gesammelt':'Sources Gathered',
647
+ 'Multi-Perspektiven-Debatten zu Schlüsselfragen. Jeder Brain liefert seine Sichtweise basierend auf Prinzipien, Hypothesen und Vorhersagen.':'Multi-perspective debates on key questions. Each brain provides its viewpoint based on principles, hypotheses, and predictions.',
648
+ 'Debatten gesamt':'Total Debates','Offen':'Open','Synthesiert':'Synthesized','Letzte Debatten':'Recent Debates',
649
+ 'Advocatus Diaboli — Prinzip-Challenges':'Advocatus Diaboli — Principle Challenges',
650
+ 'Jedes Prinzip wird aktiv hinterfragt. Überlebt es die Gegenargumente, oder wird es geschwächt/widerlegt?':'Every principle is actively challenged. Does it survive the counter-arguments, or is it weakened/disproved?',
651
+ 'Verwundbarste Prinzipien':'Most Vulnerable Principles',
652
+ 'Prinzipien mit den niedrigsten Resilienz-Scores — die schwächsten Überzeugungen, die überprüft werden sollten.':'Principles with the lowest resilience scores — the weakest beliefs that should be reviewed.',
653
+ 'Watchdog — Daemon-Überwachung':'Watchdog — Daemon Monitoring',
654
+ 'Überwacht alle Brain-Daemons. Grün = gesund, Gelb = läuft aber Healthcheck fehlgeschlagen, Rot = gestoppt. Auto-Update alle 30s.':'Monitors all brain daemons. Green = healthy, Yellow = running but healthcheck failed, Red = stopped. Auto-update every 30s.',
655
+ 'Plugins — Erweiterungen':'Plugins — Extensions','Dienst-Statistik':'Service Statistics',
656
+ 'Alle Engines auf einen Blick':'All Engines at a Glance',
657
+ 'Grün = aktiv, Gelb = bereit, Grau = aus. Die Zahl zeigt wie viele Gedanken die Engine produziert hat.':'Green = active, Yellow = ready, Gray = off. The number shows how many thoughts the engine has produced.',
658
+ 'Verbunden':'Connected','Getrennt':'Disconnected','Warte...':'Waiting...','Brain arbeitet':'Brain active','Ruhig':'Idle',
659
+ 'Gesund':'Healthy','Eingeschränkt':'Degraded','Kritisch':'Critical',
660
+ 'Warte auf Gedanken...':'Waiting for thoughts...','Durchbruch!':'Breakthrough!','Bemerkenswert':'Notable',
661
+ 'Warte auf KI-Daten...':'Waiting for AI data...','Kein KI-Service aktiv':'No AI service active',
662
+ 'KI-Anfragen':'AI Requests','Tokens verbraucht':'Tokens Used','Cache Treffer':'Cache Hits',
663
+ 'Anfragen/Stunde':'Requests/Hour','Antwortzeit':'Response Time','KI-Fehler':'AI Errors',
664
+ 'Budget pro Stunde':'Hourly Budget','Budget pro Tag':'Daily Budget','KI-Modell:':'AI Model:','Anbieter:':'Providers:',
665
+ 'Keine Fehler — alles läuft!':'No errors — all systems running!','Gelöst':'Resolved','Unbekannter Fehler':'Unknown error',
666
+ 'Lernt aus Fehlern, verbessert Code':'Learns from errors, improves code','Paper Trading, Signal-Analyse':'Paper trading, signal analysis','Content-Strategie, Engagement':'Content strategy, engagement',
667
+ 'Online':'Online','Offline':'Offline',
668
+ 'Noch keine Zusammenhänge gefunden':'No correlations found yet','Noch keine Korrelationen gefunden':'No correlations found yet',
669
+ 'Nicht verfügbar':'Not available','Aktiv':'Active','Deaktiviert':'Disabled','Deaktivieren':'Disable','Aktivieren':'Enable','Standard':'Standard',
670
+ 'Gesendet':'Sent','Empfangen':'Received','Noch kein Sync passiert':'No sync yet',
671
+ 'Zeit':'Time','Richtung':'Direction','Partner':'Peer','Elemente':'Items','Akzeptiert':'Accepted',
672
+ 'Brain hat sich noch nicht selbst verbessert':'Brain hasn\'t improved itself yet','Noch keine Verbesserungen':'No improvements yet',
673
+ 'Angewendet':'Applied','Wird getestet':'Testing','Bereit':'Ready','Vorgeschlagen':'Proposed','Generiert':'Generated','Abgelehnt':'Rejected','Zurückgesetzt':'Rolled Back',
674
+ 'Verbesserung':'Improvement','Dateien:':'Files:',
675
+ 'Keine aktiven Missionen':'No active missions','Aufteilen':'Decompose','Sammeln':'Gather','Zusammenfassen':'Synthesize',
676
+ 'Fertig':'Complete','Tiefgehend':'Deep','Schnell':'Quick','Quellen':'Sources','Gestartet:':'Started:','Fertig:':'Completed:',
677
+ 'Noch keine Debatten gestartet':'No debates started yet','Perspektiven':'Perspectives','Konsens:':'Consensus:',
678
+ 'Noch keine Challenges durchgeführt':'No challenges performed yet','Keine verwundbaren Prinzipien':'No vulnerable principles',
679
+ 'Kein Watchdog konfiguriert — starte Brain mit <code>brain start</code>':'No watchdog configured — start Brain with <code>brain start</code>',
680
+ 'Gestoppt':'Stopped','Problem':'Problem','Laufzeit':'Uptime','Neustarts':'Restarts','Letzter Crash':'Last Crash',
681
+ 'Alle Systeme laufen':'All Systems Running','Dienste offline':'services offline','Dienste mit Problemen':'services with problems',
682
+ 'Dienste überwacht':'services monitored','laufen':'running','gesund':'healthy',
683
+ 'Gesamt-Neustarts':'Total Restarts','Längste Laufzeit':'Longest Uptime','Dienste':'Services',
684
+ 'Keine Plugins installiert':'No plugins installed','Geladen':'Loaded','Keine Engines':'No engines',
685
+ 'Strategien':'Strategies','BORG AKTIV':'BORG ACTIVE','gesendet':'sent','empfangen':'received',
686
+ 'Der Lern-Kreislauf':'The Learning Cycle','Aktivität & Missionen':'Activity & Missions',
687
+ }};
688
+ let currentLang = localStorage.getItem('brain-lang') || 'en';
689
+ function t(text) { if (currentLang === 'en' && translations.en[text]) return translations.en[text]; return text; }
690
+ function setLang(lang) {
691
+ currentLang = lang; localStorage.setItem('brain-lang', lang);
692
+ document.getElementById('langToggle').textContent = lang.toUpperCase();
693
+ updateStaticTexts(); renderAll();
694
+ }
695
+ function updateStaticTexts() {
696
+ document.querySelectorAll('[data-t]').forEach(el => { el.textContent = t(el.dataset.t); });
697
+ }
698
+ function renderAll() {
699
+ const active = document.querySelector('.nav-item.active');
700
+ if (active) document.getElementById('pageTitle').textContent = getTitle(active.dataset.page);
701
+ updateConnection(); updatePulse();
702
+ renderEcosystem(); renderEngines(); renderWatchdog(); renderPlugins();
703
+ renderBorg(); renderAnalytics(); renderLLM(); renderErrors();
704
+ renderSelfMod(); renderMissions(); renderKnowledge(); renderDebates();
705
+ if (state.thoughts.length) renderThoughts();
706
+ }
707
+ function getLocale() { return currentLang === 'de' ? 'de-DE' : 'en-US'; }
708
+
612
709
  // ── Navigation ────────────────────────────────────────────
710
+ function getTitle(page) {
711
+ const titles = {
712
+ overview:'Ecosystem Overview', learning:t('Der Lern-Kreislauf'), trading:'Trading Flow',
713
+ marketing:'Marketing Flow', crossbrain:'Cross-Brain & Borg', activity:t('Aktivität & Missionen'),
714
+ debates:'Debates & Challenges', infra:t('Infrastruktur')
715
+ }; return titles[page] || '';
716
+ }
613
717
  const titles = {
614
718
  overview:'Ecosystem Overview',
615
719
  learning:'Der Lern-Kreislauf',
@@ -626,7 +730,7 @@ document.querySelectorAll('.nav-item').forEach(item => {
626
730
  document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
627
731
  item.classList.add('active');
628
732
  document.getElementById('page-' + item.dataset.page).classList.add('active');
629
- document.getElementById('pageTitle').textContent = titles[item.dataset.page] || '';
733
+ document.getElementById('pageTitle').textContent = getTitle(item.dataset.page);
630
734
  });
631
735
  });
632
736
 
@@ -651,7 +755,7 @@ function connectSSE() {
651
755
 
652
756
  function updateConnection() {
653
757
  const b = document.getElementById('connectionBadge');
654
- b.textContent = state.connected ? 'Verbunden' : 'Getrennt';
758
+ b.textContent = state.connected ? t('Verbunden') : t('Getrennt');
655
759
  b.className = 'badge ' + (state.connected ? 'badge-ok' : 'badge-err');
656
760
  }
657
761
 
@@ -684,12 +788,12 @@ function addThought(t) {
684
788
  function renderThoughts() {
685
789
  const el = document.getElementById('thoughtStream');
686
790
  const cnt = document.getElementById('thoughtCount');
687
- if (!state.thoughts.length) { el.innerHTML = '<div class="empty">Warte auf Gedanken...</div>'; cnt.textContent = ''; return; }
791
+ if (!state.thoughts.length) { el.innerHTML = `<div class="empty">${t('Warte auf Gedanken...')}</div>`; cnt.textContent = ''; return; }
688
792
  cnt.textContent = `(${state.thoughts.length})`;
689
793
  el.innerHTML = state.thoughts.slice(0, 50).map(t => {
690
- const time = new Date(t.timestamp).toLocaleTimeString('de-DE', { hour:'2-digit', minute:'2-digit', second:'2-digit' });
794
+ const time = new Date(t.timestamp).toLocaleTimeString(getLocale(), { hour:'2-digit', minute:'2-digit', second:'2-digit' });
691
795
  const sigClass = t.significance === 'breakthrough' ? 'sig-breakthrough' : t.significance === 'notable' ? 'sig-notable' : 'sig-routine';
692
- const sigLabel = t.significance === 'breakthrough' ? 'Durchbruch!' : t.significance === 'notable' ? 'Bemerkenswert' : '';
796
+ const sigLabel = t.significance === 'breakthrough' ? window.t('Durchbruch!') : t.significance === 'notable' ? window.t('Bemerkenswert') : '';
693
797
  return `<div class="thought-item">
694
798
  <span class="thought-time">${time}</span>
695
799
  <span class="thought-engine" style="color:var(--cyan)">${t.engine}</span>
@@ -704,10 +808,10 @@ function updatePulse() {
704
808
  const dot = document.getElementById('pulseDot');
705
809
  const label = document.getElementById('pulseLabel');
706
810
  const age = Date.now() - state.lastThoughtTime;
707
- if (state.lastThoughtTime === 0) { dot.className = 'pulse-dot off'; label.textContent = 'Warte...'; return; }
708
- if (age < 30000) { dot.className = 'pulse-dot'; label.textContent = 'Brain arbeitet'; }
811
+ if (state.lastThoughtTime === 0) { dot.className = 'pulse-dot off'; label.textContent = t('Warte...'); return; }
812
+ if (age < 30000) { dot.className = 'pulse-dot'; label.textContent = t('Brain arbeitet'); }
709
813
  else if (age < 120000) { dot.className = 'pulse-dot idle'; label.textContent = 'Idle'; }
710
- else { dot.className = 'pulse-dot off'; label.textContent = 'Ruhig'; }
814
+ else { dot.className = 'pulse-dot off'; label.textContent = t('Ruhig'); }
711
815
  }
712
816
  setInterval(updatePulse, 5000);
713
817
 
@@ -715,28 +819,28 @@ setInterval(updatePulse, 5000);
715
819
  function renderLLM() {
716
820
  const el = document.getElementById('llmCard');
717
821
  const s = state.llm;
718
- if (!s) { el.innerHTML = '<div class="empty">Kein KI-Service aktiv</div>'; return; }
822
+ if (!s) { el.innerHTML = `<div class="empty">${t('Kein KI-Service aktiv')}</div>`; return; }
719
823
 
720
824
  const hourPct = s.tokensThisHour && s.budgetRemainingHour != null ? Math.min(100, (s.tokensThisHour / (s.tokensThisHour + s.budgetRemainingHour)) * 100) : 0;
721
825
  const dayPct = s.tokensToday && s.budgetRemainingDay != null ? Math.min(100, (s.tokensToday / (s.tokensToday + s.budgetRemainingDay)) * 100) : 0;
722
826
 
723
827
  el.innerHTML = `
724
828
  <div class="llm-grid">
725
- <div class="llm-stat"><div class="llm-stat-value">${s.totalCalls ?? 0}</div><div class="llm-stat-label">KI-Anfragen</div></div>
726
- <div class="llm-stat"><div class="llm-stat-value">${formatK(s.totalTokens ?? 0)}</div><div class="llm-stat-label">Tokens verbraucht</div></div>
727
- <div class="llm-stat"><div class="llm-stat-value">${s.cacheHitRate != null ? (s.cacheHitRate * 100).toFixed(0) + '%' : '--'}</div><div class="llm-stat-label">Cache Treffer</div></div>
728
- <div class="llm-stat"><div class="llm-stat-value">${s.callsThisHour ?? 0}</div><div class="llm-stat-label">Anfragen/Stunde</div></div>
729
- <div class="llm-stat"><div class="llm-stat-value">${s.averageLatencyMs ? Math.round(s.averageLatencyMs) + 'ms' : '--'}</div><div class="llm-stat-label">Antwortzeit</div></div>
730
- <div class="llm-stat"><div class="llm-stat-value">${s.errors ?? 0}</div><div class="llm-stat-label">KI-Fehler</div></div>
829
+ <div class="llm-stat"><div class="llm-stat-value">${s.totalCalls ?? 0}</div><div class="llm-stat-label">${t('KI-Anfragen')}</div></div>
830
+ <div class="llm-stat"><div class="llm-stat-value">${formatK(s.totalTokens ?? 0)}</div><div class="llm-stat-label">${t('Tokens verbraucht')}</div></div>
831
+ <div class="llm-stat"><div class="llm-stat-value">${s.cacheHitRate != null ? (s.cacheHitRate * 100).toFixed(0) + '%' : '--'}</div><div class="llm-stat-label">${t('Cache Treffer')}</div></div>
832
+ <div class="llm-stat"><div class="llm-stat-value">${s.callsThisHour ?? 0}</div><div class="llm-stat-label">${t('Anfragen/Stunde')}</div></div>
833
+ <div class="llm-stat"><div class="llm-stat-value">${s.averageLatencyMs ? Math.round(s.averageLatencyMs) + 'ms' : '--'}</div><div class="llm-stat-label">${t('Antwortzeit')}</div></div>
834
+ <div class="llm-stat"><div class="llm-stat-value">${s.errors ?? 0}</div><div class="llm-stat-label">${t('KI-Fehler')}</div></div>
731
835
  </div>
732
836
  <div style="margin-top:12px">
733
- <div style="display:flex;justify-content:space-between;font-size:10px;color:var(--text-dim);margin-bottom:2px"><span>Budget pro Stunde</span><span>${formatK(s.tokensThisHour ?? 0)} / ${formatK((s.tokensThisHour ?? 0) + (s.budgetRemainingHour ?? 0))}</span></div>
837
+ <div style="display:flex;justify-content:space-between;font-size:10px;color:var(--text-dim);margin-bottom:2px"><span>${t('Budget pro Stunde')}</span><span>${formatK(s.tokensThisHour ?? 0)} / ${formatK((s.tokensThisHour ?? 0) + (s.budgetRemainingHour ?? 0))}</span></div>
734
838
  <div class="llm-bar"><div class="llm-bar-fill" style="width:${hourPct}%;background:${hourPct > 80 ? 'var(--red)' : hourPct > 50 ? 'var(--orange)' : 'var(--cyan)'}"></div></div>
735
- <div style="display:flex;justify-content:space-between;font-size:10px;color:var(--text-dim);margin:8px 0 2px"><span>Budget pro Tag</span><span>${formatK(s.tokensToday ?? 0)} / ${formatK((s.tokensToday ?? 0) + (s.budgetRemainingDay ?? 0))}</span></div>
839
+ <div style="display:flex;justify-content:space-between;font-size:10px;color:var(--text-dim);margin:8px 0 2px"><span>${t('Budget pro Tag')}</span><span>${formatK(s.tokensToday ?? 0)} / ${formatK((s.tokensToday ?? 0) + (s.budgetRemainingDay ?? 0))}</span></div>
736
840
  <div class="llm-bar"><div class="llm-bar-fill" style="width:${dayPct}%;background:${dayPct > 80 ? 'var(--red)' : dayPct > 50 ? 'var(--orange)' : 'var(--green)'}"></div></div>
737
841
  </div>
738
- ${s.model ? `<div style="margin-top:10px;font-size:10px;color:var(--text-dim)">KI-Modell: ${s.model}</div>` : ''}
739
- ${s.providers ? `<div style="margin-top:4px;font-size:10px;color:var(--text-dim)">Anbieter: ${s.providers.map(p => `<span style="color:${p.available ? 'var(--green)' : 'var(--red)'}">${p.name}</span>`).join(', ')}</div>` : ''}
842
+ ${s.model ? `<div style="margin-top:10px;font-size:10px;color:var(--text-dim)">${t('KI-Modell:')} ${s.model}</div>` : ''}
843
+ ${s.providers ? `<div style="margin-top:4px;font-size:10px;color:var(--text-dim)">${t('Anbieter:')} ${s.providers.map(p => `<span style="color:${p.available ? 'var(--green)' : 'var(--red)'}">${p.name}</span>`).join(', ')}</div>` : ''}
740
844
  `;
741
845
  }
742
846
 
@@ -745,18 +849,18 @@ function renderErrors() {
745
849
  const el = document.getElementById('errorFeed');
746
850
  const cnt = document.getElementById('errorCount');
747
851
  const d = state.errors;
748
- if (!d) { el.innerHTML = '<div class="empty">Keine Fehler — alles läuft!</div>'; cnt.textContent = ''; return; }
852
+ if (!d) { el.innerHTML = `<div class="empty">${t('Keine Fehler — alles läuft!')}</div>`; cnt.textContent = ''; return; }
749
853
  const errors = d.errors || d;
750
- if (!Array.isArray(errors) || !errors.length) { el.innerHTML = '<div class="empty">Keine Fehler — alles läuft!</div>'; cnt.textContent = ''; return; }
854
+ if (!Array.isArray(errors) || !errors.length) { el.innerHTML = `<div class="empty">${t('Keine Fehler — alles läuft!')}</div>`; cnt.textContent = ''; return; }
751
855
  cnt.textContent = `(${errors.length})`;
752
856
  el.innerHTML = errors.slice(0, 20).map(e => {
753
- const time = e.timestamp ? new Date(e.timestamp).toLocaleTimeString('de-DE', { hour:'2-digit', minute:'2-digit' }) : '';
857
+ const time = e.timestamp ? new Date(e.timestamp).toLocaleTimeString(getLocale(), { hour:'2-digit', minute:'2-digit' }) : '';
754
858
  const level = e.resolved ? 'warn' : 'err';
755
- const msg = e.message || e.error_message || e.title || 'Unbekannter Fehler';
859
+ const msg = e.message || e.error_message || e.title || t('Unbekannter Fehler');
756
860
  const source = e.source || e.project || '';
757
861
  return `<div class="error-item">
758
862
  <span class="thought-time">${time}</span>
759
- <span class="error-level ${level}">${e.resolved ? 'Gelöst' : 'Fehler'}</span>
863
+ <span class="error-level ${level}">${e.resolved ? t('Gelöst') : t('Fehler')}</span>
760
864
  ${source ? `<span style="font-size:11px;color:var(--cyan);min-width:60px">${escHtml(source)}</span>` : ''}
761
865
  <span class="error-msg">${escHtml(msg)}</span>
762
866
  </div>`;
@@ -768,7 +872,7 @@ function renderSelfMod() {
768
872
  const d = state.selfmod;
769
873
  if (!d || !d.status) {
770
874
  setText('sm-total', 0); setText('sm-applied', 0); setText('sm-testing', 0); setText('sm-failed', 0);
771
- document.getElementById('selfModFeed').innerHTML = '<div class="empty">Brain hat sich noch nicht selbst verbessert</div>';
875
+ document.getElementById('selfModFeed').innerHTML = `<div class="empty">${t('Brain hat sich noch nicht selbst verbessert')}</div>`;
772
876
  return;
773
877
  }
774
878
  const s = d.status;
@@ -780,11 +884,11 @@ function renderSelfMod() {
780
884
 
781
885
  const hist = d.history || [];
782
886
  const el = document.getElementById('selfModFeed');
783
- if (!hist.length) { el.innerHTML = '<div class="empty">Noch keine Verbesserungen</div>'; return; }
887
+ if (!hist.length) { el.innerHTML = `<div class="empty">${t('Noch keine Verbesserungen')}</div>`; return; }
784
888
  el.innerHTML = hist.map(m => {
785
- const statusMap = { applied:'Angewendet', testing:'Wird getestet', ready:'Bereit', proposed:'Vorgeschlagen', generating:'Generiert', failed:'Fehlgeschlagen', rejected:'Abgelehnt', rolled_back:'Zurückgesetzt' };
889
+ const statusMap = { applied:t('Angewendet'), testing:t('Wird getestet'), ready:t('Bereit'), proposed:t('Vorgeschlagen'), generating:t('Generiert'), failed:t('Fehlgeschlagen'), rejected:t('Abgelehnt'), rolled_back:t('Zurückgesetzt') };
786
890
  const statusClass = m.status === 'applied' ? 'mod-applied' : m.status === 'testing' || m.status === 'generating' ? 'mod-testing' : m.status === 'failed' || m.status === 'rejected' ? 'mod-failed' : 'mod-proposed';
787
- const time = m.created_at ? new Date(m.created_at).toLocaleString('de-DE', { day:'2-digit', month:'2-digit', hour:'2-digit', minute:'2-digit' }) : '';
891
+ const time = m.created_at ? new Date(m.created_at).toLocaleString(getLocale(), { day:'2-digit', month:'2-digit', hour:'2-digit', minute:'2-digit' }) : '';
788
892
  const actions = (m.status === 'ready' || m.status === 'proposed') ?
789
893
  `<div style="margin-top:4px;display:flex;gap:6px">
790
894
  <button onclick="selfmodAction(${m.id},'approve')" style="background:var(--green);color:#fff;border:none;border-radius:4px;padding:2px 10px;cursor:pointer;font-size:11px">Approve</button>
@@ -794,9 +898,9 @@ function renderSelfMod() {
794
898
  return `<div class="mod-item">
795
899
  <span class="mod-status ${statusClass}">${statusMap[m.status] || m.status}</span>
796
900
  <div style="flex:1">
797
- <div class="mod-title">${escHtml(m.title || 'Verbesserung')}${riskBadge}</div>
901
+ <div class="mod-title">${escHtml(m.title || t('Verbesserung'))}${riskBadge}</div>
798
902
  <div class="mod-detail">${escHtml(m.problem_description || '')} ${time ? `<span style="float:right">${time}</span>` : ''}</div>
799
- ${m.target_files?.length ? `<div style="font-size:10px;color:var(--text-dim);margin-top:2px">Dateien: ${m.target_files.map(f => f.split('/').pop()).join(', ')}</div>` : ''}
903
+ ${m.target_files?.length ? `<div style="font-size:10px;color:var(--text-dim);margin-top:2px">${t('Dateien:')} ${m.target_files.map(f => f.split('/').pop()).join(', ')}</div>` : ''}
800
904
  ${actions}
801
905
  </div>
802
906
  </div>`;
@@ -807,10 +911,10 @@ async function selfmodAction(id, action) {
807
911
  try {
808
912
  const res = await fetch(`/api/selfmod/${action}`, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({id}) });
809
913
  const data = await res.json();
810
- if (!res.ok) { alert(`Fehler: ${data.error || 'Unbekannt'}`); return; }
914
+ if (!res.ok) { alert(`${t('Fehler')}: ${data.error || 'Unknown'}`); return; }
811
915
  // Refresh selfmod data
812
916
  fetch('/api/selfmod').then(r => r.json()).then(d => { state.selfmod = d; renderSelfMod(); });
813
- } catch(e) { alert(`Fehler: ${e.message}`); }
917
+ } catch(e) { alert(`${t('Fehler')}: ${e.message}`); }
814
918
  }
815
919
 
816
920
  // ── Mission Tracker ───────────────────────────────────────
@@ -818,7 +922,7 @@ function renderMissions() {
818
922
  const d = state.missions;
819
923
  if (!d || !d.status) {
820
924
  setText('ms-active', 0); setText('ms-completed', 0); setText('ms-sources', 0);
821
- document.getElementById('missionList').innerHTML = '<div class="empty">Keine aktiven Missionen</div>';
925
+ document.getElementById('missionList').innerHTML = `<div class="empty">${t('Keine aktiven Missionen')}</div>`;
822
926
  return;
823
927
  }
824
928
  const s = d.status;
@@ -828,24 +932,24 @@ function renderMissions() {
828
932
 
829
933
  const list = d.list || [];
830
934
  const el = document.getElementById('missionList');
831
- if (!list.length) { el.innerHTML = '<div class="empty">Keine aktiven Missionen</div>'; return; }
935
+ if (!list.length) { el.innerHTML = `<div class="empty">${t('Keine aktiven Missionen')}</div>`; return; }
832
936
  const phases = ['decomposing','gathering','hypothesizing','analyzing','synthesizing'];
833
- const phaseLabels = { decomposing:'Aufteilen', gathering:'Sammeln', hypothesizing:'Ideen bilden', analyzing:'Analysieren', synthesizing:'Zusammenfassen' };
937
+ const phaseLabels = { decomposing:t('Aufteilen'), gathering:t('Sammeln'), hypothesizing:t('Ideen bilden'), analyzing:t('Analysieren'), synthesizing:t('Zusammenfassen') };
834
938
  el.innerHTML = list.slice(0, 10).map(m => {
835
939
  const statusIdx = phases.indexOf(m.status);
836
940
  const phaseHtml = phases.map((p, i) => {
837
941
  const cls = m.status === 'complete' ? 'done' : m.status === 'failed' ? (i <= statusIdx ? 'fail' : '') : (i < statusIdx ? 'done' : i === statusIdx ? 'running' : '');
838
942
  return `<div class="mission-phase ${cls}" title="${phaseLabels[p] || p}"></div>`;
839
943
  }).join('');
840
- const statusText = m.status === 'complete' ? 'Fertig' : m.status === 'failed' ? 'Fehlgeschlagen' : phaseLabels[m.status] || m.status;
841
- const depth = m.depth === 'deep' ? 'Tiefgehend' : m.depth === 'quick' ? 'Schnell' : 'Standard';
944
+ const statusText = m.status === 'complete' ? t('Fertig') : m.status === 'failed' ? t('Fehlgeschlagen') : phaseLabels[m.status] || m.status;
945
+ const depth = m.depth === 'deep' ? t('Tiefgehend') : m.depth === 'quick' ? t('Schnell') : t('Standard');
842
946
  return `<div class="mission-card">
843
947
  <div class="mission-topic">${escHtml(m.topic || 'Mission')}</div>
844
- <div style="font-size:11px;color:var(--text-dim)">${statusText} — ${depth} — ${m.sourceCount || 0} Quellen</div>
948
+ <div style="font-size:11px;color:var(--text-dim)">${statusText} — ${depth} — ${m.sourceCount || 0} ${t('Quellen')}</div>
845
949
  <div class="mission-phases">${phaseHtml}</div>
846
950
  <div class="mission-meta">
847
- <span>Gestartet: ${m.createdAt ? new Date(m.createdAt).toLocaleString('de-DE', { day:'2-digit', month:'2-digit', hour:'2-digit', minute:'2-digit' }) : '?'}</span>
848
- ${m.completedAt ? `<span>Fertig: ${new Date(m.completedAt).toLocaleString('de-DE', { day:'2-digit', month:'2-digit', hour:'2-digit', minute:'2-digit' })}</span>` : ''}
951
+ <span>${t('Gestartet:')} ${m.createdAt ? new Date(m.createdAt).toLocaleString(getLocale(), { day:'2-digit', month:'2-digit', hour:'2-digit', minute:'2-digit' }) : '?'}</span>
952
+ ${m.completedAt ? `<span>${t('Fertig:')} ${new Date(m.completedAt).toLocaleString(getLocale(), { day:'2-digit', month:'2-digit', hour:'2-digit', minute:'2-digit' })}</span>` : ''}
849
953
  </div>
850
954
  </div>`;
851
955
  }).join('');
@@ -908,7 +1012,7 @@ function renderEcosystem() {
908
1012
  const hb = document.getElementById('healthBadge');
909
1013
  const h = eco.health;
910
1014
  if (h) {
911
- hb.textContent = h.status === 'healthy' ? 'Gesund' : h.status === 'degraded' ? 'Eingeschränkt' : 'Kritisch';
1015
+ hb.textContent = h.status === 'healthy' ? t('Gesund') : h.status === 'degraded' ? t('Eingeschränkt') : t('Kritisch');
912
1016
  hb.className = 'badge ' + (h.status === 'healthy' ? 'badge-ok' : h.status === 'degraded' ? 'badge-warn' : 'badge-err');
913
1017
  const score = h.score || 0;
914
1018
  document.getElementById('gaugeArc').setAttribute('stroke-dasharray', `${(score / 100) * 172} 172`);
@@ -918,7 +1022,7 @@ function renderEcosystem() {
918
1022
  const container = document.getElementById('brainCards');
919
1023
  const brainNames = ['brain', 'trading-brain', 'marketing-brain'];
920
1024
  const labels = { brain:'Brain', 'trading-brain':'Trading-Brain', 'marketing-brain':'Marketing-Brain' };
921
- const descs = { brain:'Lernt aus Fehlern, verbessert Code', 'trading-brain':'Paper Trading, Signal-Analyse', 'marketing-brain':'Content-Strategie, Engagement' };
1025
+ const descs = { brain:t('Lernt aus Fehlern, verbessert Code'), 'trading-brain':t('Paper Trading, Signal-Analyse'), 'marketing-brain':t('Content-Strategie, Engagement') };
922
1026
  const classes = { brain:'brain-brain', 'trading-brain':'brain-trading', 'marketing-brain':'brain-marketing' };
923
1027
  container.innerHTML = brainNames.map(name => {
924
1028
  const b = (eco.brains || []).find(x => x.name === name) || { name, available:false };
@@ -926,7 +1030,7 @@ function renderEcosystem() {
926
1030
  <div class="brain-status"><span class="dot ${b.available ? 'dot-on' : 'dot-off'}"></span><span class="brain-name">${labels[name]}</span></div>
927
1031
  <div style="font-size:11px;color:var(--text-dim);margin-bottom:6px">${descs[name]}</div>
928
1032
  <div class="brain-meta">
929
- <span>${b.available ? 'Online' : 'Offline'}</span>
1033
+ <span>${b.available ? t('Online') : t('Offline')}</span>
930
1034
  ${b.version ? `<span>v${b.version}</span>` : ''}${b.pid ? `<span>PID ${b.pid}</span>` : ''}
931
1035
  ${b.uptime ? `<span>${fmtUp(b.uptime)}</span>` : ''}${b.methods ? `<span>${b.methods} Tools</span>` : ''}
932
1036
  </div></div>`;
@@ -937,7 +1041,7 @@ function renderEcosystem() {
937
1041
 
938
1042
  function renderCorrelations(c) {
939
1043
  const el = document.getElementById('correlationList');
940
- if (!c.length) { el.innerHTML = '<div class="empty">Noch keine Zusammenhänge gefunden</div>'; return; }
1044
+ if (!c.length) { el.innerHTML = `<div class="empty">${t('Noch keine Zusammenhänge gefunden')}</div>`; return; }
941
1045
  el.innerHTML = c.slice(0, 10).map(x => `<div style="padding:6px 0;border-bottom:1px solid var(--border);font-size:12px">
942
1046
  <span style="color:var(--cyan)">${x.sourceA}/${x.eventA}</span> <span style="color:var(--text-dim)">&#x2194;</span>
943
1047
  <span style="color:var(--magenta)">${x.sourceB}/${x.eventB}</span>
@@ -959,7 +1063,7 @@ function renderEngines() {
959
1063
 
960
1064
  function renderGrid(id, engines, showBrain = false) {
961
1065
  const el = document.getElementById(id); if (!el) return;
962
- if (!engines.length) { el.innerHTML = '<div class="empty">Keine Engines</div>'; return; }
1066
+ if (!engines.length) { el.innerHTML = `<div class="empty">${t('Keine Engines')}</div>`; return; }
963
1067
  el.innerHTML = engines.map(e => {
964
1068
  const lastTs = e.lastActive || e.lastActivity || 0;
965
1069
  const count = e.metrics?.totalThoughts ?? e.thoughtCount ?? 0;
@@ -1006,7 +1110,7 @@ function renderAnalytics() {
1006
1110
  setText('mp-campaigns', num(m.campaigns));
1007
1111
  setText('marketingCampaigns', num(m.campaigns));
1008
1112
  setText('marketingTopContent', num(m.templates) > 0 ? num(m.templates) + ' Templates' : '--');
1009
- setText('marketingAudience', num(m.strategies) > 0 ? num(m.strategies) + ' Strategien' : '--');
1113
+ setText('marketingAudience', num(m.strategies) > 0 ? num(m.strategies) + ' ' + t('Strategien') : '--');
1010
1114
  }
1011
1115
  }
1012
1116
  function num(v) { if (v == null) return 0; if (typeof v === 'object') return v.total || v.count || v.length || Object.keys(v).length || 0; return Number(v) || 0; }
@@ -1015,13 +1119,13 @@ function num(v) { if (v == null) return 0; if (typeof v === 'object') return v.t
1015
1119
  function renderWatchdog() {
1016
1120
  const el = document.getElementById('watchdogCards');
1017
1121
  const d = state.watchdog || [];
1018
- if (!d.length) { el.innerHTML = '<div class="empty">Kein Watchdog konfiguriert — starte Brain mit <code>brain start</code></div>'; return; }
1122
+ if (!d.length) { el.innerHTML = `<div class="empty">${t('Kein Watchdog konfiguriert — starte Brain mit <code>brain start</code>')}</div>`; return; }
1019
1123
 
1020
1124
  // Daemon cards — color-coded
1021
1125
  el.innerHTML = d.map(x => {
1022
1126
  const borderColor = !x.running ? 'var(--red)' : x.healthy ? 'var(--green)' : 'var(--orange)';
1023
1127
  const bgColor = !x.running ? 'rgba(239,68,68,0.08)' : x.healthy ? 'rgba(34,197,94,0.08)' : 'rgba(234,179,8,0.08)';
1024
- const statusText = !x.running ? 'Gestoppt' : x.healthy ? 'Gesund' : 'Problem';
1128
+ const statusText = !x.running ? t('Gestoppt') : x.healthy ? t('Gesund') : t('Problem');
1025
1129
  const statusIcon = !x.running ? '&#x1F534;' : x.healthy ? '&#x1F7E2;' : '&#x1F7E1;';
1026
1130
  const uptime = x.uptime ? fmtUp(x.uptime / 1000) : '-';
1027
1131
  return `<div class="card" style="border-left:3px solid ${borderColor};background:${bgColor};padding:16px">
@@ -1031,9 +1135,9 @@ function renderWatchdog() {
1031
1135
  </div>
1032
1136
  <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;font-size:12px">
1033
1137
  <div><span style="color:var(--text-dim)">PID</span><br><span style="font-weight:600;font-size:14px">${x.pid || '-'}</span></div>
1034
- <div><span style="color:var(--text-dim)">Laufzeit</span><br><span style="font-weight:600;font-size:14px">${uptime}</span></div>
1035
- <div><span style="color:var(--text-dim)">Neustarts</span><br><span style="font-weight:600;font-size:14px;color:${x.restarts > 0 ? 'var(--orange)' : 'inherit'}">${x.restarts || 0}</span></div>
1036
- <div><span style="color:var(--text-dim)">Letzter Crash</span><br><span style="font-weight:600;font-size:11px">${x.lastCrash ? new Date(x.lastCrash).toLocaleString('de') : '-'}</span></div>
1138
+ <div><span style="color:var(--text-dim)">${t('Laufzeit')}</span><br><span style="font-weight:600;font-size:14px">${uptime}</span></div>
1139
+ <div><span style="color:var(--text-dim)">${t('Neustarts')}</span><br><span style="font-weight:600;font-size:14px;color:${x.restarts > 0 ? 'var(--orange)' : 'inherit'}">${x.restarts || 0}</span></div>
1140
+ <div><span style="color:var(--text-dim)">${t('Letzter Crash')}</span><br><span style="font-weight:600;font-size:11px">${x.lastCrash ? new Date(x.lastCrash).toLocaleString(getLocale()) : '-'}</span></div>
1037
1141
  </div>
1038
1142
  </div>`;
1039
1143
  }).join('');
@@ -1042,7 +1146,7 @@ function renderWatchdog() {
1042
1146
  const hc = document.getElementById('healthCheckCard');
1043
1147
  const ok = d.every(x => x.running && x.healthy), off = d.filter(x => !x.running).length;
1044
1148
  const unhealthy = d.filter(x => x.running && !x.healthy).length;
1045
- hc.innerHTML = `<div style="display:flex;gap:20px;align-items:center"><span style="font-size:32px">${ok?'&#x2705;':off?'&#x1F6A8;':'&#x26A0;'}</span><div><div style="font-size:15px;font-weight:600;color:${ok?'var(--green)':off?'var(--red)':'var(--orange)'}">${ok?'Alle Systeme laufen':off?`${off} Dienste offline`:`${unhealthy} Dienste mit Problemen`}</div><div style="font-size:12px;color:var(--text-dim);margin-top:4px">${d.length} Dienste überwacht &bull; ${d.filter(x=>x.running).length} laufen &bull; ${d.filter(x=>x.running&&x.healthy).length} gesund</div></div></div>`;
1149
+ hc.innerHTML = `<div style="display:flex;gap:20px;align-items:center"><span style="font-size:32px">${ok?'&#x2705;':off?'&#x1F6A8;':'&#x26A0;'}</span><div><div style="font-size:15px;font-weight:600;color:${ok?'var(--green)':off?'var(--red)':'var(--orange)'}">${ok?t('Alle Systeme laufen'):off?`${off} ${t('Dienste offline')}`:`${unhealthy} ${t('Dienste mit Problemen')}`}</div><div style="font-size:12px;color:var(--text-dim);margin-top:4px">${d.length} ${t('Dienste überwacht')} &bull; ${d.filter(x=>x.running).length} ${t('laufen')} &bull; ${d.filter(x=>x.running&&x.healthy).length} ${t('gesund')}</div></div></div>`;
1046
1150
 
1047
1151
  // Stats card
1048
1152
  const sc = document.getElementById('watchdogStatsCard');
@@ -1050,32 +1154,32 @@ function renderWatchdog() {
1050
1154
  const avgUptime = d.filter(x => x.uptime).map(x => x.uptime);
1051
1155
  const maxUp = avgUptime.length ? fmtUp(Math.max(...avgUptime) / 1000) : '-';
1052
1156
  sc.innerHTML = `<div style="display:flex;gap:24px;font-size:13px">
1053
- <div><span style="color:var(--text-dim)">Gesamt-Neustarts</span><br><span style="font-size:20px;font-weight:700;color:${totalRestarts>0?'var(--orange)':'var(--green)'}">${totalRestarts}</span></div>
1054
- <div><span style="color:var(--text-dim)">Längste Laufzeit</span><br><span style="font-size:20px;font-weight:700">${maxUp}</span></div>
1055
- <div><span style="color:var(--text-dim)">Dienste</span><br><span style="font-size:20px;font-weight:700">${d.length}</span></div>
1157
+ <div><span style="color:var(--text-dim)">${t('Gesamt-Neustarts')}</span><br><span style="font-size:20px;font-weight:700;color:${totalRestarts>0?'var(--orange)':'var(--green)'}">${totalRestarts}</span></div>
1158
+ <div><span style="color:var(--text-dim)">${t('Längste Laufzeit')}</span><br><span style="font-size:20px;font-weight:700">${maxUp}</span></div>
1159
+ <div><span style="color:var(--text-dim)">${t('Dienste')}</span><br><span style="font-size:20px;font-weight:700">${d.length}</span></div>
1056
1160
  </div>`;
1057
1161
  }
1058
1162
 
1059
1163
  function renderPlugins() {
1060
1164
  const el = document.getElementById('pluginCard');
1061
1165
  const p = state.plugins || [];
1062
- if (!p.length) { el.innerHTML = '<div class="empty">Keine Plugins installiert</div>'; return; }
1063
- el.innerHTML = p.map(x => `<div style="padding:8px 0;border-bottom:1px solid var(--border);display:flex;justify-content:space-between"><div><div style="font-weight:600;font-size:13px">${x.name}</div><div style="font-size:11px;color:var(--text-dim)">${x.description||''} v${x.version}</div></div><span class="tag tag-green">${x.status||'Geladen'}</span></div>`).join('');
1166
+ if (!p.length) { el.innerHTML = `<div class="empty">${t('Keine Plugins installiert')}</div>`; return; }
1167
+ el.innerHTML = p.map(x => `<div style="padding:8px 0;border-bottom:1px solid var(--border);display:flex;justify-content:space-between"><div><div style="font-weight:600;font-size:13px">${x.name}</div><div style="font-size:11px;color:var(--text-dim)">${x.description||''} v${x.version}</div></div><span class="tag tag-green">${x.status||t('Geladen')}</span></div>`).join('');
1064
1168
  }
1065
1169
 
1066
1170
  // ── Render: Borg ──────────────────────────────────────────
1067
1171
  function renderBorg() {
1068
1172
  const b = state.borg;
1069
1173
  const sEl = document.getElementById('borgStatus'), btn = document.getElementById('borgToggle'), det = document.getElementById('borgDetails'), hist = document.getElementById('borgHistory');
1070
- if (!b || !b.status) { sEl.textContent = 'Nicht verfügbar'; btn.disabled = true; return; }
1174
+ if (!b || !b.status) { sEl.textContent = t('Nicht verfügbar'); btn.disabled = true; return; }
1071
1175
  const s = b.status;
1072
- sEl.innerHTML = `<span class="dot ${s.enabled?'dot-on':'dot-off'}" style="margin-right:6px"></span>${s.enabled?'Aktiv':'Deaktiviert'} &mdash; ${s.mode || 'Standard'}`;
1073
- btn.disabled = false; btn.className = s.enabled ? 'btn btn-active' : 'btn'; btn.textContent = s.enabled ? 'Deaktivieren' : 'Aktivieren';
1074
- det.innerHTML = `<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;font-size:12px;margin-top:8px"><div><span style="color:var(--text-dim)">Syncs</span><br><strong>${s.totalSyncs||0}</strong></div><div><span style="color:var(--text-dim)">Gesendet</span><br><strong>${s.totalSent||0}</strong></div><div><span style="color:var(--text-dim)">Empfangen</span><br><strong>${s.totalReceived||0}</strong></div></div>`;
1176
+ sEl.innerHTML = `<span class="dot ${s.enabled?'dot-on':'dot-off'}" style="margin-right:6px"></span>${s.enabled?t('Aktiv'):t('Deaktiviert')} &mdash; ${s.mode || t('Standard')}`;
1177
+ btn.disabled = false; btn.className = s.enabled ? 'btn btn-active' : 'btn'; btn.textContent = s.enabled ? t('Deaktivieren') : t('Aktivieren');
1178
+ det.innerHTML = `<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;font-size:12px;margin-top:8px"><div><span style="color:var(--text-dim)">Syncs</span><br><strong>${s.totalSyncs||0}</strong></div><div><span style="color:var(--text-dim)">${t('Gesendet')}</span><br><strong>${s.totalSent||0}</strong></div><div><span style="color:var(--text-dim)">${t('Empfangen')}</span><br><strong>${s.totalReceived||0}</strong></div></div>`;
1075
1179
  const h = b.history || [];
1076
- if (!h.length) { hist.innerHTML = '<div class="empty">Noch kein Sync passiert</div>'; return; }
1077
- hist.innerHTML = `<table class="tbl"><thead><tr><th>Zeit</th><th>Richtung</th><th>Partner</th><th>Elemente</th><th>Akzeptiert</th></tr></thead><tbody>` +
1078
- h.slice(-15).reverse().map(x => `<tr><td>${new Date(x.timestamp).toLocaleTimeString('de-DE')}</td><td>${x.direction==='sent'?'&#x2B06;':'&#x2B07;'} ${x.direction==='sent'?'Gesendet':'Empfangen'}</td><td>${x.peer}</td><td>${x.itemCount}</td><td>${x.accepted}</td></tr>`).join('') + '</tbody></table>';
1180
+ if (!h.length) { hist.innerHTML = `<div class="empty">${t('Noch kein Sync passiert')}</div>`; return; }
1181
+ hist.innerHTML = `<table class="tbl"><thead><tr><th>${t('Zeit')}</th><th>${t('Richtung')}</th><th>${t('Partner')}</th><th>${t('Elemente')}</th><th>${t('Akzeptiert')}</th></tr></thead><tbody>` +
1182
+ h.slice(-15).reverse().map(x => `<tr><td>${new Date(x.timestamp).toLocaleTimeString(getLocale())}</td><td>${x.direction==='sent'?'&#x2B06;':'&#x2B07;'} ${x.direction==='sent'?t('Gesendet'):t('Empfangen')}</td><td>${x.peer}</td><td>${x.itemCount}</td><td>${x.accepted}</td></tr>`).join('') + '</tbody></table>';
1079
1183
  }
1080
1184
  document.getElementById('borgToggle').addEventListener('click', async () => {
1081
1185
  if (!state.borg?.status) return;
@@ -1096,7 +1200,7 @@ function renderDebates() {
1096
1200
  // Recent debates
1097
1201
  const list = d.recent || [];
1098
1202
  const listEl = document.getElementById('debateList');
1099
- if (!list.length) { listEl.innerHTML = '<div class="empty">Noch keine Debatten gestartet</div>'; }
1203
+ if (!list.length) { listEl.innerHTML = `<div class="empty">${t('Noch keine Debatten gestartet')}</div>`; }
1100
1204
  else {
1101
1205
  listEl.innerHTML = list.map(db => {
1102
1206
  const statusCol = db.status === 'synthesized' ? 'var(--green)' : db.status === 'open' ? 'var(--yellow)' : 'var(--cyan)';
@@ -1106,15 +1210,15 @@ function renderDebates() {
1106
1210
  <strong style="color:var(--cyan)">#${db.id}: ${db.question?.substring(0,80)||'?'}</strong>
1107
1211
  <span style="color:${statusCol};font-size:11px;text-transform:uppercase">${db.status}</span>
1108
1212
  </div>
1109
- <div style="font-size:11px;color:var(--text-dim);margin-top:4px">${persp} Perspektiven | ${db.created_at ? new Date(db.created_at).toLocaleString('de-DE') : ''}</div>
1110
- ${db.synthesis ? `<div style="font-size:11px;margin-top:4px;color:var(--green)">Konsens: ${(db.synthesis.consensus||'').substring(0,120)}...</div>` : ''}
1213
+ <div style="font-size:11px;color:var(--text-dim);margin-top:4px">${persp} ${t('Perspektiven')} | ${db.created_at ? new Date(db.created_at).toLocaleString(getLocale()) : ''}</div>
1214
+ ${db.synthesis ? `<div style="font-size:11px;margin-top:4px;color:var(--green)">${t('Konsens:')} ${(db.synthesis.consensus||'').substring(0,120)}...</div>` : ''}
1111
1215
  </div>`;
1112
1216
  }).join('');
1113
1217
  }
1114
1218
  // Challenges
1115
1219
  const chList = d.challenges || [];
1116
1220
  const chEl = document.getElementById('challengeList');
1117
- if (!chList.length) { chEl.innerHTML = '<div class="empty">Noch keine Challenges durchgeführt</div>'; }
1221
+ if (!chList.length) { chEl.innerHTML = `<div class="empty">${t('Noch keine Challenges durchgeführt')}</div>`; }
1118
1222
  else {
1119
1223
  chEl.innerHTML = chList.map(c => {
1120
1224
  const icon = c.outcome === 'survived' ? '\u2705' : c.outcome === 'weakened' ? '\u26A0\uFE0F' : '\u274C';
@@ -1131,7 +1235,7 @@ function renderDebates() {
1131
1235
  // Vulnerable
1132
1236
  const vulList = d.vulnerable || [];
1133
1237
  const vulEl = document.getElementById('vulnerableList');
1134
- if (!vulList.length) { vulEl.innerHTML = '<div class="empty">Keine verwundbaren Prinzipien</div>'; }
1238
+ if (!vulList.length) { vulEl.innerHTML = `<div class="empty">${t('Keine verwundbaren Prinzipien')}</div>`; }
1135
1239
  else {
1136
1240
  vulEl.innerHTML = vulList.map(v => {
1137
1241
  const pct = ((v.resilienceScore || 0) * 100).toFixed(0);
@@ -1282,7 +1386,7 @@ function initCrossBrainCanvas() {
1282
1386
  }
1283
1387
  if(borgEnabled) {
1284
1388
  ctx.fillStyle='rgba(170,136,255,0.7)'; ctx.font='10px Segoe UI,sans-serif'; ctx.textAlign='center';
1285
- ctx.fillText(`BORG AKTIV \u2022 ${borgSent} gesendet \u2022 ${borgRecv} empfangen`, w/2, h-8);
1389
+ ctx.fillText(`${t('BORG AKTIV')} \u2022 ${borgSent} ${t('gesendet')} \u2022 ${borgRecv} ${t('empfangen')}`, w/2, h-8);
1286
1390
  }
1287
1391
  ctx.restore(); requestAnimationFrame(draw);
1288
1392
  }
@@ -1296,6 +1400,8 @@ function formatK(n) { if(n>=1e6) return (n/1e6).toFixed(1)+'M'; if(n>=1e3) retur
1296
1400
  function escHtml(s) { const d=document.createElement('div'); d.textContent=s; return d.innerHTML; }
1297
1401
 
1298
1402
  // ── Init ──────────────────────────────────────────────────
1403
+ document.getElementById('langToggle').textContent = currentLang.toUpperCase();
1404
+ updateStaticTexts();
1299
1405
  connectSSE(); loadInitial(); initCrossBrainCanvas();
1300
1406
  window.addEventListener('resize', () => { if(state.ecosystem?.brains) drawPeerGraph(state.ecosystem.brains); });
1301
1407
  </script>