init: extract deesk-coach from qognio-bot-widget-template@d2c816f

Source files (src/) and rendered bundle (www/) extracted on 2026-04-29T01:35:46+02:00.
Adds nginx:alpine Dockerfile + docker-compose.yml (Caddy-labels) so the bot
runs stand-alone or as a per-customer template clone.

Parent monorepo commit: d2c816f3edbc9760802a11b29ff4151c7aad4b46
Bot version: 2026-04-24
This commit is contained in:
Qognio Bot Extract 2026-04-29 01:35:46 +02:00
commit 4b9d25b43d
16 changed files with 3544 additions and 0 deletions

7
.dockerignore Normal file
View file

@ -0,0 +1,7 @@
.git
.gitignore
README.md
bot.json
src/
docker-compose.yml
*.md

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
.DS_Store
*.log
*.tmp
node_modules/

13
Dockerfile Normal file
View file

@ -0,0 +1,13 @@
# Static-bundle bot — nginx:alpine serves www/ on port 80.
FROM nginx:1.27-alpine
# nginx config: gzip + cache headers + index.html no-store
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Static bundle
COPY www/ /usr/share/nginx/html/
# Run as non-root via nginx's built-in unprivileged image features
EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -q --spider http://127.0.0.1/index.html || exit 1

67
README.md Normal file
View file

@ -0,0 +1,67 @@
# Nora — Deeskalations-Coach
Nora — dein Deeskalations-Coach. Szenario-basiert Konfliktsituationen sicher durchtrainieren. Läuft im deutschen Bunker.
```
slug : deesk-coach
version : 2026-04-24
accent : #3b82f6
runtime : nginx:alpine (static bundle)
template : qognio-bot-template-core (former qognio-bot-widget-template)
```
## Layout
```
.
├── src/ source — config.yaml, welcome.html, curricula.json, etc.
├── www/ rendered, directly servable static bundle
├── Dockerfile nginx:alpine + www/ → port 80
├── docker-compose.yml bot-host pattern (Caddy-labels, restart unless-stopped)
├── nginx.conf gzip + cache + SPA fallback
└── bot.json metadata + parent_core_commit
```
## Run locally
```bash
docker compose up --build
# → http://localhost (you'll need to tweak ports for local-only use)
```
## Re-render after upstream core changes
This repo only stores src + rendered output; the rendering engine lives in
`qognio-bot-template-core`. To pull in core changes:
```bash
cd /path/to/qognio-bot-template-core
./scripts/render.sh deesk-coach --bot-repo /path/to/this/repo
git -C /path/to/this/repo commit -am "render: refresh from core@<sha>"
```
## Per-customer copy (template usage)
This repo is a **template**. To clone for a customer:
```bash
git clone <this-repo> my-customer-deesk-coach
cd my-customer-deesk-coach
# tweak src/config.yaml (slug, bot_key_value, accent), src/welcome.html, src/curricula.json
docker compose -f docker-compose.yml up --build
```
## Deploy to qognio bot-host (.42 LXC pattern — legacy)
The bot-manager spawns LXC containers named after the slug. Push www/ via:
```bash
ssh fmh@46.243.203.42
sudo lxc file push /tmp/www/* deesk-coach/var/www/html/
```
(Or run the docker-compose pattern on a Docker host — same network as Caddy.)
---
Generated by `qognio-bot-template-core/scripts/extract-to-repo.sh` on 2026-04-29T01:35:46+02:00.

14
bot.json Normal file
View file

@ -0,0 +1,14 @@
{
"slug": "deesk-coach",
"name": "Nora",
"title": "Deeskalations-Coach",
"tagline": "Deeskalations-Coach",
"description": "Nora — dein Deeskalations-Coach. Szenario-basiert Konfliktsituationen sicher durchtrainieren. Läuft im deutschen Bunker.",
"version": "2026-04-24",
"accent": "#3b82f6",
"extracted_from": "qognio-bot-widget-template",
"parent_core_commit": "d2c816f3edbc9760802a11b29ff4151c7aad4b46",
"extracted_at": "2026-04-29T01:35:46+02:00",
"runtime": "nginx:alpine",
"default_port": 80
}

20
docker-compose.yml Normal file
View file

@ -0,0 +1,20 @@
# Stand-alone bot container.
# Designed for the "caddy" external network on the bot host (qognio pattern).
# Override the hostname via SLUG env var if you reuse this template per customer.
services:
bot:
build: .
image: qognio/bot-deesk-coach:${TAG:-latest}
container_name: bot-deesk-coach
restart: unless-stopped
networks:
- caddy
labels:
caddy: "deesk-coach.on.qognio.com"
caddy.reverse_proxy: "{{upstreams 80}}"
qognio.bot.slug: "deesk-coach"
qognio.bot.version: "2026-04-24"
networks:
caddy:
external: true

27
nginx.conf Normal file
View file

@ -0,0 +1,27 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# gzip
gzip on;
gzip_vary on;
gzip_types text/css application/javascript application/json image/svg+xml text/plain;
gzip_min_length 512;
# index.html: never cache (so welcome screen / wiring updates land instantly)
location = /index.html {
add_header Cache-Control "no-store, must-revalidate" always;
}
# static assets: cache 1h
location ~* \.(?:css|js|json|svg|png|jpe?g|webp|gif|ico|woff2?)$ {
add_header Cache-Control "public, max-age=3600" always;
try_files $uri =404;
}
location / {
try_files $uri $uri/ /index.html;
}
}

19
src/check-badges.js Normal file
View file

@ -0,0 +1,19 @@
// Erster Dialog — 1 Quiz bestanden (irgendein Modul)
if ((state.completedQuizzes || 0) >= 1) unlockBadge('erste_deeskalation');
// GFK-Meister:in — Rosenberg-Modul komplett (Modul 'gfk' in completedCurricula)
if ((state.completedCurricula || []).includes('gfk')) unlockBadge('gfk_meister');
// Glasl-Detektiv — Grundlagen-Modul komplett
if ((state.completedCurricula || []).includes('grundlagen')) unlockBadge('glasl_expert');
// CPI-zertifiziert — Deeskalations-Phasen-Modul komplett
if ((state.completedCurricula || []).includes('phasen')) unlockBadge('cpi_certified');
// Active Listener — Aktiv-Zuhören-Modul komplett
if ((state.completedCurricula || []).includes('zuhoeren')) unlockBadge('active_listener');
// Körpersprache-Pro — Körpersprache-Modul komplett
if ((state.completedCurricula || []).includes('koerpersprache')) unlockBadge('body_language_pro');
// 2-Wochen-Disziplin — 14-Tage-Streak
if (state.maxStreak >= 14) unlockBadge('streak_14');
// Deeskalations-Profi — alle 10 Module complete
if ((state.completedCurricula || []).length >= 10) unlockBadge('all_rounder');
// Night Owl (late-night Lerner)
const h = new Date().getHours();
if (h >= 22) unlockBadge('night_owl');

33
src/config.yaml Normal file
View file

@ -0,0 +1,33 @@
slug: deesk-coach
bot_name: Nora
bot_title: "Deeskalations-Coach"
brand_letter: N
title: "Nora · Deeskalations-Coach"
tagline: "Deeskalations-Coach"
tagline_short: "Deeskalations-Coach"
meta_description: "Nora — dein Deeskalations-Coach. Szenario-basiert Konfliktsituationen sicher durchtrainieren. Läuft im deutschen Bunker."
bot_key_var: __NORA_KEY__
bot_key_value: qb_n6r3dj46hmku
ls_prefix: nora
bot_version: "2026-04-24"
# Color theme (Nora — blue)
accent: "#3b82f6"
accent_2: "#60a5fa"
accent_dark: "#1d4ed8"
accent_rgb: "59, 130, 246"
success_color: "#10b981"
msg_strong_color: "#bfdbfe"
# UI Labels
tab_flash_label: Karten
tab_curriculum_label: Toolkit
curriculum_long_label: Toolkit
curriculum_comment: TOOLKIT
# Bot personality
quiz_intro_hint: "Wähle ein Modul — Nora generiert realistische Deeskalations-Szenario-Fragen."
quiz_verb: erstellt
quiz_noun: "Szenario-Fragen"
flash_intro_hint: "Nora erstellt Karteikarten zu einem Thema. Bewerte dein Erinnerungsvermögen — das System wiederholt schwere Karten öfter (SM-2)."
flash_verb: erstellt

201
src/curricula.json Normal file
View file

@ -0,0 +1,201 @@
{
"version": "2026-04-24",
"updated": "2026-04-24",
"curricula": [
{
"id": "foundations",
"title": "1 · Fundament",
"short": "Glasl, Thomas-Kilmann, Konfliktarten",
"icon": "shield",
"color": "#3b82f6",
"description": "Was ist ein Konflikt, wie eskaliert er, und welchen Stil wähle ich wann? Glasl-9-Stufen, Thomas-Kilmann-Matrix, Konfliktarten.",
"source_md": "00-grundlagen-konflikt.md",
"modules": [
{
"id": "grundlagen",
"title": "Konflikt-Grundlagen & Glasl-9-Stufen",
"objectives": [
"9 Eskalationsstufen nach Glasl sicher benennen",
"Drei Phasen (Win/Win → Win/Lose → Lose/Lose) einschätzen",
"Wann reicht Selbstmoderation vs. wann Dritte nötig"
],
"topics": ["Glasl 9 Stufen", "Win/Win", "Lose/Lose", "Konfliktarten"],
"difficulty": "mittel",
"source_heading": "Die 9 Eskalationsstufen nach Friedrich Glasl"
},
{
"id": "stile",
"title": "Konfliktstile (Thomas-Kilmann)",
"objectives": [
"5 Stile erkennen: Kämpfen, Anpassen, Vermeiden, Zusammenarbeiten, Kompromiss",
"Eigenen Default-Stil reflektieren",
"Stil bewusst wechseln, wenn der Default nicht passt"
],
"topics": ["Competing", "Accommodating", "Avoiding", "Collaborating", "Compromising"],
"difficulty": "einfach",
"source_heading": "Die 5 Konfliktstile nach Thomas-Kilmann"
}
]
},
{
"id": "communication",
"title": "2 · Verbale Werkzeuge",
"short": "GFK, aktives Zuhören",
"icon": "handshake",
"color": "#60a5fa",
"description": "Die zwei wichtigsten Sprech- und Hör-Werkzeuge: Rosenbergs 4 Schritte der GFK und Rogers' aktives Zuhören.",
"source_md": "01-gfk-rosenberg.md, 02-aktives-zuhoeren.md",
"modules": [
{
"id": "gfk",
"title": "GFK (Rosenberg) — 4 Schritte",
"objectives": [
"Beobachtung, Gefühl, Bedürfnis, Bitte sauber trennen",
"Typische Fallen erkennen (Bewertung, Pseudo-Gefühl, Strategie, Forderung)",
"GFK-Sätze in Eskalationssituationen formulieren"
],
"topics": ["Beobachtung", "Gefühl", "Bedürfnis", "Bitte", "Empathisches Hören"],
"difficulty": "mittel",
"source_heading": "Die 4 Schritte"
},
{
"id": "zuhoeren",
"title": "Aktives Zuhören (Rogers)",
"objectives": [
"Echtheit, Akzeptanz, Empathie als Grundhaltungen verstehen",
"Paraphrasieren, Reformulieren, Verbalisieren unterscheiden",
"Kommunikations-Sperren (Rat, Bewertung, Bagatellisieren) vermeiden"
],
"topics": ["Kongruenz", "Paraphrasieren", "Spiegeln", "Gordon-Sperren"],
"difficulty": "mittel",
"source_heading": "Die 3 Grundhaltungen nach Rogers"
}
]
},
{
"id": "body",
"title": "3 · Körper & Phase",
"short": "Körpersprache, Stimme, CPI-Phasen",
"icon": "star",
"color": "#2563eb",
"description": "Was der Körper sagt, bevor das Wort fällt. Dazu das CPI-Phasen-Modell und Verbal Judo.",
"source_md": "03-koerpersprache-ruhe.md, 04-deeskalations-phasen.md",
"modules": [
{
"id": "koerpersprache",
"title": "Körpersprache, Stimme & Atmung",
"objectives": [
"45°-Stellung, offene Hände, Abstand einsetzen",
"Stimme (Lautstärke, Tempo, Tonlage) bewusst steuern",
"4-7-8-Atmung zur eigenen Regulation nutzen"
],
"topics": ["45°-Stellung", "Offene Hände", "Distanz-Zonen", "Tonlage", "4-7-8"],
"difficulty": "einfach",
"source_heading": "Der Grund-Kanon"
},
{
"id": "phasen",
"title": "Deeskalations-Phasen (CPI, Verbal Judo)",
"objectives": [
"CPI-4-Phasen-Modell (Anxiety → Defensive → Risk → Tension Reduction)",
"Passende Helfer-Haltung je Phase (Supportive/Directive/Safety/Rapport)",
"L.E.A.P.S.-Akronym und Verbal-Judo-Leitsätze"
],
"topics": ["CPI", "Verbal Judo", "L.E.A.P.S.", "Mikro-Skripte"],
"difficulty": "mittel",
"source_heading": "CPI-Modell"
}
]
},
{
"id": "practice",
"title": "4 · Praxis & Risiko",
"short": "Gefährdungs-Assessment, Szenarien",
"icon": "detective",
"color": "#1d4ed8",
"description": "Frühwarnzeichen lesen, Triggerumgebung verstehen, und konkrete Szenarien aus Retail / Pflege / Security / ÖPNV / Schule.",
"source_md": "05-gefaehrdungs-assessment.md, 06-szenarien-branche.md",
"modules": [
{
"id": "assessment",
"title": "Gefährdungs-Assessment & P-S-R",
"objectives": [
"P-S-R-Modell (Physiology, Stage, Response) anwenden",
"Typische Trigger (Machtlosigkeit, Warten, Schmerz, Alkohol/Drogen) benennen",
"Ampel-System 🟢🟡🟠🔴 in 30 Sekunden scannen"
],
"topics": ["P-S-R", "Trigger", "Ampel-System", "Umgebungs-Risiko"],
"difficulty": "mittel",
"source_heading": "Das P-S-R-Modell"
},
{
"id": "szenarien",
"title": "Branchen-Szenarien",
"objectives": [
"Retail: Rückgabe-Verweigerung, Preis-Streit",
"Pflege: Angehörige, Demenz, Notaufnahme",
"Security/ÖPNV/Schule: Einlass, Ticket, Elterngespräch"
],
"topics": ["Retail", "Pflege", "Security", "ÖPNV", "Schule"],
"difficulty": "mittel",
"source_heading": "A) Einzelhandel / Kundenservice"
}
]
},
{
"id": "after",
"title": "5 · Danach & Recht",
"short": "Selbstfürsorge, Rechtsrahmen",
"icon": "medal",
"color": "#1e3a8a",
"description": "Was kommt nach dem Vorfall: Debriefing, CISM, PTSD-Warnzeichen, plus Rechtsrahmen (Notwehr, Hausrecht, AGG).",
"source_md": "07-selbstfuersorge-nachbereitung.md, 08-rechtsrahmen.md, 09-faq-situationen.md",
"modules": [
{
"id": "selbstfuersorge",
"title": "Selbstfürsorge & Debriefing (CISM)",
"objectives": [
"Akute Nachbereitung (5-Min-Regel, Atemübung)",
"Strukturiertes Debriefing + CISM-Modell",
"PTSD-Warnzeichen erkennen, Wege zu Hilfe (BG, 116 117, TelefonSeelsorge)"
],
"topics": ["Debriefing", "CISM", "Peer-Support", "PTBS", "BG-Meldung"],
"difficulty": "mittel",
"source_heading": "Akute Nachbereitung"
},
{
"id": "recht",
"title": "Rechtsrahmen & FAQ",
"objectives": [
"§ 32 Notwehr + § 34 Notstand korrekt abgrenzen",
"§ 127 StPO (Festnahme) und § 903 BGB (Hausrecht) kennen",
"Dokumentationspflichten nach Vorfall (BG, Verbandbuch, Anzeige-Fristen)"
],
"topics": ["§ 32 StGB", "§ 34 StGB", "§ 127 StPO", "§ 903 BGB", "AGG", "Doku"],
"difficulty": "schwer",
"source_heading": "§ 32 StGB — Notwehr"
}
]
}
],
"badges": [
{"id": "erste_deeskalation", "title": "Erster Dialog", "icon": "award", "description": "1. Quiz bestanden — der Anfang ist gemacht."},
{"id": "gfk_meister", "title": "GFK-Meister:in", "icon": "handshake", "description": "Rosenberg-Modul mit ≥80% abgeschlossen."},
{"id": "glasl_expert", "title": "Glasl-Detektiv", "icon": "detective", "description": "Konflikt-Grundlagen-Modul abgeschlossen."},
{"id": "cpi_certified", "title": "CPI-zertifiziert", "icon": "shield", "description": "Deeskalations-Phasen-Modul abgeschlossen."},
{"id": "active_listener", "title": "Active Listener", "icon": "star", "description": "Aktiv-Zuhören-Modul abgeschlossen."},
{"id": "body_language_pro", "title": "Körpersprache-Pro", "icon": "medal", "description": "Körpersprache-Modul abgeschlossen."},
{"id": "streak_14", "title": "2-Wochen-Disziplin", "icon": "flame", "description": "14 Tage in Folge aktiv gewesen."},
{"id": "all_rounder", "title": "Deeskalations-Profi", "icon": "crown", "description": "Alle 10 Module abgeschlossen."},
{"id": "night_owl", "title": "Nachteule", "icon": "moon", "description": "Nach 22 Uhr gelernt."}
],
"levels": [
{"min": 0, "title": "Einsteiger:in"},
{"min": 50, "title": "Tagelöhner:in"},
{"min": 200, "title": "Lerner:in"},
{"min": 500, "title": "Erfahren"},
{"min": 1250, "title": "Multiplikator:in"},
{"min": 2500, "title": "Coach"},
{"min": 5000, "title": "Mediator:in"}
]
}

4
src/levels-fallback.js Normal file
View file

@ -0,0 +1,4 @@
{ min: 0, title: 'Einsteiger:in' }, { min: 50, title: 'Praktiker:in' },
{ min: 200, title: 'Erfahrene:r' }, { min: 500, title: 'Profi' },
{ min: 1250, title: 'Multiplikator:in' }, { min: 2500, title: 'Coach' },
{ min: 5000, title: 'Mediator:in' }

25
src/welcome.html Normal file
View file

@ -0,0 +1,25 @@
<h2>Hi, ich bin Nora.</h2>
<p>Ich helfe dir, Konflikte früh zu erkennen, zu deeskalieren und sicher durchzukommen. Übung macht souverän — lass uns anfangen mit einer kurzen Situations-Einschätzung. <strong>Mach Konflikte zu Begegnungen.</strong></p>
<div class="mode-grid">
<button class="mode-card" data-goto="chat">
<strong>Chat</strong>
<span>Frag mich zu Deeskalation, GFK, Körpersprache, Recht.</span>
</button>
<button class="mode-card" data-goto="quiz">
<strong>Quiz</strong>
<span>Szenario-Fragen aus deinem Alltag — mit XP.</span>
</button>
<button class="mode-card" data-goto="flash">
<strong>Flashcards</strong>
<span>Begriffe, Sätze, Modelle — Spaced-Repetition.</span>
</button>
<button class="mode-card" data-goto="progress">
<strong>Fortschritt</strong>
<span>XP, Streaks, Badges, Level.</span>
</button>
<button class="mode-card" data-goto="curriculum">
<strong>Toolkit</strong>
<span>10 Module + direkte „Ich-brauch-grad"-Einträge.</span>
</button>
</div>
<p style="font-size:.82rem;color:var(--text-mute)">Kurz gesagt: Chat zum Verstehen → Quiz zum Testen → Flashcards zum Merken → Case-Requests (im Chat) für echte Rollenspiele.</p>

1750
www/app.js Normal file

File diff suppressed because it is too large Load diff

201
www/curricula.json Normal file
View file

@ -0,0 +1,201 @@
{
"version": "2026-04-24",
"updated": "2026-04-24",
"curricula": [
{
"id": "foundations",
"title": "1 · Fundament",
"short": "Glasl, Thomas-Kilmann, Konfliktarten",
"icon": "shield",
"color": "#3b82f6",
"description": "Was ist ein Konflikt, wie eskaliert er, und welchen Stil wähle ich wann? Glasl-9-Stufen, Thomas-Kilmann-Matrix, Konfliktarten.",
"source_md": "00-grundlagen-konflikt.md",
"modules": [
{
"id": "grundlagen",
"title": "Konflikt-Grundlagen & Glasl-9-Stufen",
"objectives": [
"9 Eskalationsstufen nach Glasl sicher benennen",
"Drei Phasen (Win/Win → Win/Lose → Lose/Lose) einschätzen",
"Wann reicht Selbstmoderation vs. wann Dritte nötig"
],
"topics": ["Glasl 9 Stufen", "Win/Win", "Lose/Lose", "Konfliktarten"],
"difficulty": "mittel",
"source_heading": "Die 9 Eskalationsstufen nach Friedrich Glasl"
},
{
"id": "stile",
"title": "Konfliktstile (Thomas-Kilmann)",
"objectives": [
"5 Stile erkennen: Kämpfen, Anpassen, Vermeiden, Zusammenarbeiten, Kompromiss",
"Eigenen Default-Stil reflektieren",
"Stil bewusst wechseln, wenn der Default nicht passt"
],
"topics": ["Competing", "Accommodating", "Avoiding", "Collaborating", "Compromising"],
"difficulty": "einfach",
"source_heading": "Die 5 Konfliktstile nach Thomas-Kilmann"
}
]
},
{
"id": "communication",
"title": "2 · Verbale Werkzeuge",
"short": "GFK, aktives Zuhören",
"icon": "handshake",
"color": "#60a5fa",
"description": "Die zwei wichtigsten Sprech- und Hör-Werkzeuge: Rosenbergs 4 Schritte der GFK und Rogers' aktives Zuhören.",
"source_md": "01-gfk-rosenberg.md, 02-aktives-zuhoeren.md",
"modules": [
{
"id": "gfk",
"title": "GFK (Rosenberg) — 4 Schritte",
"objectives": [
"Beobachtung, Gefühl, Bedürfnis, Bitte sauber trennen",
"Typische Fallen erkennen (Bewertung, Pseudo-Gefühl, Strategie, Forderung)",
"GFK-Sätze in Eskalationssituationen formulieren"
],
"topics": ["Beobachtung", "Gefühl", "Bedürfnis", "Bitte", "Empathisches Hören"],
"difficulty": "mittel",
"source_heading": "Die 4 Schritte"
},
{
"id": "zuhoeren",
"title": "Aktives Zuhören (Rogers)",
"objectives": [
"Echtheit, Akzeptanz, Empathie als Grundhaltungen verstehen",
"Paraphrasieren, Reformulieren, Verbalisieren unterscheiden",
"Kommunikations-Sperren (Rat, Bewertung, Bagatellisieren) vermeiden"
],
"topics": ["Kongruenz", "Paraphrasieren", "Spiegeln", "Gordon-Sperren"],
"difficulty": "mittel",
"source_heading": "Die 3 Grundhaltungen nach Rogers"
}
]
},
{
"id": "body",
"title": "3 · Körper & Phase",
"short": "Körpersprache, Stimme, CPI-Phasen",
"icon": "star",
"color": "#2563eb",
"description": "Was der Körper sagt, bevor das Wort fällt. Dazu das CPI-Phasen-Modell und Verbal Judo.",
"source_md": "03-koerpersprache-ruhe.md, 04-deeskalations-phasen.md",
"modules": [
{
"id": "koerpersprache",
"title": "Körpersprache, Stimme & Atmung",
"objectives": [
"45°-Stellung, offene Hände, Abstand einsetzen",
"Stimme (Lautstärke, Tempo, Tonlage) bewusst steuern",
"4-7-8-Atmung zur eigenen Regulation nutzen"
],
"topics": ["45°-Stellung", "Offene Hände", "Distanz-Zonen", "Tonlage", "4-7-8"],
"difficulty": "einfach",
"source_heading": "Der Grund-Kanon"
},
{
"id": "phasen",
"title": "Deeskalations-Phasen (CPI, Verbal Judo)",
"objectives": [
"CPI-4-Phasen-Modell (Anxiety → Defensive → Risk → Tension Reduction)",
"Passende Helfer-Haltung je Phase (Supportive/Directive/Safety/Rapport)",
"L.E.A.P.S.-Akronym und Verbal-Judo-Leitsätze"
],
"topics": ["CPI", "Verbal Judo", "L.E.A.P.S.", "Mikro-Skripte"],
"difficulty": "mittel",
"source_heading": "CPI-Modell"
}
]
},
{
"id": "practice",
"title": "4 · Praxis & Risiko",
"short": "Gefährdungs-Assessment, Szenarien",
"icon": "detective",
"color": "#1d4ed8",
"description": "Frühwarnzeichen lesen, Triggerumgebung verstehen, und konkrete Szenarien aus Retail / Pflege / Security / ÖPNV / Schule.",
"source_md": "05-gefaehrdungs-assessment.md, 06-szenarien-branche.md",
"modules": [
{
"id": "assessment",
"title": "Gefährdungs-Assessment & P-S-R",
"objectives": [
"P-S-R-Modell (Physiology, Stage, Response) anwenden",
"Typische Trigger (Machtlosigkeit, Warten, Schmerz, Alkohol/Drogen) benennen",
"Ampel-System 🟢🟡🟠🔴 in 30 Sekunden scannen"
],
"topics": ["P-S-R", "Trigger", "Ampel-System", "Umgebungs-Risiko"],
"difficulty": "mittel",
"source_heading": "Das P-S-R-Modell"
},
{
"id": "szenarien",
"title": "Branchen-Szenarien",
"objectives": [
"Retail: Rückgabe-Verweigerung, Preis-Streit",
"Pflege: Angehörige, Demenz, Notaufnahme",
"Security/ÖPNV/Schule: Einlass, Ticket, Elterngespräch"
],
"topics": ["Retail", "Pflege", "Security", "ÖPNV", "Schule"],
"difficulty": "mittel",
"source_heading": "A) Einzelhandel / Kundenservice"
}
]
},
{
"id": "after",
"title": "5 · Danach & Recht",
"short": "Selbstfürsorge, Rechtsrahmen",
"icon": "medal",
"color": "#1e3a8a",
"description": "Was kommt nach dem Vorfall: Debriefing, CISM, PTSD-Warnzeichen, plus Rechtsrahmen (Notwehr, Hausrecht, AGG).",
"source_md": "07-selbstfuersorge-nachbereitung.md, 08-rechtsrahmen.md, 09-faq-situationen.md",
"modules": [
{
"id": "selbstfuersorge",
"title": "Selbstfürsorge & Debriefing (CISM)",
"objectives": [
"Akute Nachbereitung (5-Min-Regel, Atemübung)",
"Strukturiertes Debriefing + CISM-Modell",
"PTSD-Warnzeichen erkennen, Wege zu Hilfe (BG, 116 117, TelefonSeelsorge)"
],
"topics": ["Debriefing", "CISM", "Peer-Support", "PTBS", "BG-Meldung"],
"difficulty": "mittel",
"source_heading": "Akute Nachbereitung"
},
{
"id": "recht",
"title": "Rechtsrahmen & FAQ",
"objectives": [
"§ 32 Notwehr + § 34 Notstand korrekt abgrenzen",
"§ 127 StPO (Festnahme) und § 903 BGB (Hausrecht) kennen",
"Dokumentationspflichten nach Vorfall (BG, Verbandbuch, Anzeige-Fristen)"
],
"topics": ["§ 32 StGB", "§ 34 StGB", "§ 127 StPO", "§ 903 BGB", "AGG", "Doku"],
"difficulty": "schwer",
"source_heading": "§ 32 StGB — Notwehr"
}
]
}
],
"badges": [
{"id": "erste_deeskalation", "title": "Erster Dialog", "icon": "award", "description": "1. Quiz bestanden — der Anfang ist gemacht."},
{"id": "gfk_meister", "title": "GFK-Meister:in", "icon": "handshake", "description": "Rosenberg-Modul mit ≥80% abgeschlossen."},
{"id": "glasl_expert", "title": "Glasl-Detektiv", "icon": "detective", "description": "Konflikt-Grundlagen-Modul abgeschlossen."},
{"id": "cpi_certified", "title": "CPI-zertifiziert", "icon": "shield", "description": "Deeskalations-Phasen-Modul abgeschlossen."},
{"id": "active_listener", "title": "Active Listener", "icon": "star", "description": "Aktiv-Zuhören-Modul abgeschlossen."},
{"id": "body_language_pro", "title": "Körpersprache-Pro", "icon": "medal", "description": "Körpersprache-Modul abgeschlossen."},
{"id": "streak_14", "title": "2-Wochen-Disziplin", "icon": "flame", "description": "14 Tage in Folge aktiv gewesen."},
{"id": "all_rounder", "title": "Deeskalations-Profi", "icon": "crown", "description": "Alle 10 Module abgeschlossen."},
{"id": "night_owl", "title": "Nachteule", "icon": "moon", "description": "Nach 22 Uhr gelernt."}
],
"levels": [
{"min": 0, "title": "Einsteiger:in"},
{"min": 50, "title": "Tagelöhner:in"},
{"min": 200, "title": "Lerner:in"},
{"min": 500, "title": "Erfahren"},
{"min": 1250, "title": "Multiplikator:in"},
{"min": 2500, "title": "Coach"},
{"min": 5000, "title": "Mediator:in"}
]
}

121
www/index.html Normal file
View file

@ -0,0 +1,121 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Nora · Deeskalations-Coach</title>
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
<meta name="theme-color" content="#0a0a0f">
<meta name="description" content="Nora — dein Deeskalations-Coach. Szenario-basiert Konfliktsituationen sicher durchtrainieren. Läuft im deutschen Bunker.">
<link rel="stylesheet" href="styles.css">
<script>window.__NORA_KEY__ = 'qb_n6r3dj46hmku';</script>
</head>
<body>
<div class="app" role="application" aria-label="Nora Deeskalations-Coach">
<header class="topbar">
<div class="brand">
<span class="brand-icon" aria-hidden="true">N</span>
<span>Nora <small>Deeskalations-Coach</small></span>
</div>
<div class="spacer"></div>
<span class="status" role="status" aria-live="polite">Online</span>
</header>
<nav class="tabbar" role="tablist" aria-label="Modi">
<button class="tab" role="tab" aria-selected="true" aria-controls="view-chat" data-mode="chat">
Chat
<span class="tab-kbd">⌃1</span>
</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="view-quiz" data-mode="quiz">
Quiz
<span class="tab-kbd">⌃2</span>
</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="view-flash" data-mode="flash">
Karten
<span class="tab-kbd">⌃3</span>
</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="view-progress" data-mode="progress">
Fortschritt
<span class="tab-kbd">⌃4</span>
</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="view-curriculum" data-mode="curriculum">
Toolkit
<span class="tab-kbd">⌃5</span>
</button>
</nav>
<main class="main">
<!-- CHAT -->
<section id="view-chat" class="view" role="tabpanel" aria-labelledby="tab-chat" data-active="true">
<div id="welcome-screen" class="welcome hidden" aria-hidden="true">
<h2>Hi, ich bin Nora.</h2>
<p>Ich helfe dir, Konflikte früh zu erkennen, zu deeskalieren und sicher durchzukommen. Übung macht souverän — lass uns anfangen mit einer kurzen Situations-Einschätzung. <strong>Mach Konflikte zu Begegnungen.</strong></p>
<div class="mode-grid">
<button class="mode-card" data-goto="chat">
<strong>Chat</strong>
<span>Frag mich zu Deeskalation, GFK, Körpersprache, Recht.</span>
</button>
<button class="mode-card" data-goto="quiz">
<strong>Quiz</strong>
<span>Szenario-Fragen aus deinem Alltag — mit XP.</span>
</button>
<button class="mode-card" data-goto="flash">
<strong>Flashcards</strong>
<span>Begriffe, Sätze, Modelle — Spaced-Repetition.</span>
</button>
<button class="mode-card" data-goto="progress">
<strong>Fortschritt</strong>
<span>XP, Streaks, Badges, Level.</span>
</button>
<button class="mode-card" data-goto="curriculum">
<strong>Toolkit</strong>
<span>10 Module + direkte „Ich-brauch-grad"-Einträge.</span>
</button>
</div>
<p style="font-size:.82rem;color:var(--text-mute)">Kurz gesagt: Chat zum Verstehen → Quiz zum Testen → Flashcards zum Merken → Case-Requests (im Chat) für echte Rollenspiele.</p>
</div>
<div id="chat-box" class="chat-box" aria-live="polite" aria-label="Gespräch"></div>
</section>
<!-- QUIZ -->
<section id="view-quiz" class="view" role="tabpanel" aria-labelledby="tab-quiz">
<div id="quiz-host"></div>
</section>
<!-- FLASHCARDS -->
<section id="view-flash" class="view" role="tabpanel" aria-labelledby="tab-flash">
<div id="flash-host"></div>
</section>
<!-- PROGRESS -->
<section id="view-progress" class="view" role="tabpanel" aria-labelledby="tab-progress">
<div id="progress-host"></div>
</section>
<!-- TOOLKIT -->
<section id="view-curriculum" class="view" role="tabpanel" aria-labelledby="tab-curr">
<div id="curr-host"></div>
</section>
</main>
<form id="composer-form" class="composer" aria-label="Nachricht verfassen">
<div id="attach-strip" class="attach-strip" aria-live="polite"></div>
<div class="composer-row">
<button type="button" class="btn-attach" id="composer-attach" aria-label="Datei anhängen" title="Datei anhängen (PDF, Bild, Text — max 5 Dateien, 8 MB)">📎</button>
<input type="file" id="composer-file" multiple accept=".pdf,.txt,.md,.csv,.json,.xml,.yaml,.yml,.log,.png,.jpg,.jpeg,.webp,.gif" hidden>
<textarea id="composer" rows="1" placeholder="Frag Nora — Enter zum Senden, Shift+Enter für Zeilenumbruch" aria-label="Nachricht"></textarea>
<button type="submit" class="btn-primary" id="composer-send">Senden</button>
</div>
</form>
<footer class="footer">
Sovereign AI · Deutscher Bunker · <a href="https://qognio.com">Qognio</a> &nbsp;·&nbsp; DSGVO-konform · Keine externen Fonts · Keine Cookies
</footer>
</div>
<div id="toast-stack" class="toast-stack" aria-live="polite"></div>
<script src="app.js"></script>
</body>
</html>

1038
www/styles.css Normal file

File diff suppressed because it is too large Load diff