init: extract bar-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-21
This commit is contained in:
Qognio Bot Extract 2026-04-29 01:35:46 +02:00
commit ab94f4a7e9
16 changed files with 4143 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 @@
# Max — Bar & Bühnen-Coach
Max — dein Bar & Bühnen-Coach. Crash-Kurs für Bar-Kräfte und Event-Crews — rechtssicher, praxisnah, Deutschland-legal. DSGVO-konform im Bunker.
```
slug : bar-coach
version : 2026-04-21
accent : #f59e0b
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 bar-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-bar-coach
cd my-customer-bar-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/* bar-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": "bar-coach",
"name": "Max",
"title": "Bar &amp; Bühnen-Coach",
"tagline": "Bar &amp; Bühnen-Coach",
"description": "Max — dein Bar & Bühnen-Coach. Crash-Kurs für Bar-Kräfte und Event-Crews — rechtssicher, praxisnah, Deutschland-legal. DSGVO-konform im Bunker.",
"version": "2026-04-21",
"accent": "#f59e0b",
"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-bar-coach:${TAG:-latest}
container_name: bot-bar-coach
restart: unless-stopped
networks:
- caddy
labels:
caddy: "bar-coach.on.qognio.com"
caddy.reverse_proxy: "{{upstreams 80}}"
qognio.bot.slug: "bar-coach"
qognio.bot.version: "2026-04-21"
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;
}
}

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

@ -0,0 +1,23 @@
// Feuer frei — 1. Quiz bestanden
if ((state.completedQuizzes || 0) >= 1) unlockBadge('erste_schicht');
// Cocktail-Ninja — alle Mixology-Submodule in completedCurricula
const mixMods = ['technik','klassiker','glas-garnitur','masse'];
if (mixMods.every(m => (state.completedCurricula || []).includes(m))) unlockBadge('cocktail_ninja');
// Jugendschutz-Watchdog — alle Jugendschutz-Fragen korrekt, mind. 5 beantwortet
if (state.moduleTotal && state.moduleTotal['juschg'] >= 5 &&
state.moduleCorrect['juschg'] === state.moduleTotal['juschg']) unlockBadge('jugendschutz_watchdog');
// DGUV-Profi — Event-Tech-Modul komplett
const dguvMods = ['dguv','vstaettvo','rigging','pyro-strom'];
if (dguvMods.every(m => (state.completedCurricula || []).includes(m))) unlockBadge('dguv_profi');
// Gast-Flüsterer — Service-Etikette-Modul komplett
const serviceMods = ['sequence','reklamation','zahlung','gast-konflikt'];
if (serviceMods.every(m => (state.completedCurricula || []).includes(m))) unlockBadge('gast_whisperer');
// Kassen-Profi — Kassen-Modul komplett
const kasseMods = ['tse','bon','kassenfuehrung','nachschau'];
if (kasseMods.every(m => (state.completedCurricula || []).includes(m))) unlockBadge('kassen_pro');
// Thekengeneral — alle 8 Curricula (alle Module aller Curricula)
if (CURRICULA && (CURRICULA.curricula || []).every(c =>
c.modules.every(m => (state.completedCurricula || []).includes(m.id)))) unlockBadge('all_rounder');
// Night Owl
const h = new Date().getHours();
if (h >= 22) unlockBadge('night_owl');

32
src/config.yaml Normal file
View file

@ -0,0 +1,32 @@
slug: bar-coach
bot_name: Max
bot_title: "Bar &amp; Bühnen-Coach"
brand_letter: M
title: "Max · Bar & Bühnen-Coach"
tagline: "Bar und Bühnen-Coach"
tagline_short: "Bar &amp; Bühnen-Coach"
meta_description: "Max — dein Bar & Bühnen-Coach. Crash-Kurs für Bar-Kräfte und Event-Crews — rechtssicher, praxisnah, Deutschland-legal. DSGVO-konform im Bunker."
bot_key_var: __MAX_KEY__
bot_key_value: qb_vdxwoq9mh6hy
ls_prefix: max
bot_version: "2026-04-21"
# Color theme (Max — amber/gold)
accent: "#f59e0b"
accent_2: "#fbbf24"
accent_dark: "#d97706"
accent_rgb: "245, 158, 11"
success_color: "#10b981"
msg_strong_color: "#fde68a"
# UI Labels
tab_flash_label: Karten
tab_curriculum_label: Know-How
curriculum_long_label: Know-How
# Bot personality
quiz_intro_hint: "Wähle ein Modul — Max baut Szenario-Fragen aus dem Bar-/Event-Alltag."
quiz_verb: baut
quiz_noun: "Szenario-Fragen"
flash_intro_hint: "Max baut Karteikarten zu einem Thema. Bewerte dein Erinnerungsvermögen — das System wiederholt schwere Karten öfter (SM-2)."
flash_verb: baut

497
src/curricula.json Normal file
View file

@ -0,0 +1,497 @@
{
"version": "2026-04-24",
"updated": "2026-04-24",
"curricula": [
{
"id": "bar-basics",
"title": "1 · Bar-Basics Recht",
"short": "JuSchG, § 43 IfSG, LMHV, HACCP",
"icon": "shield",
"color": "#f59e0b",
"description": "Die rechtlichen Mindestpflichten hinter der Theke: Jugendschutz, Belehrung nach § 43 IfSG, Lebensmittelhygiene, HACCP-Grundsätze.",
"source_md": "bar-basics.md",
"modules": [
{
"id": "juschg",
"title": "Jugendschutz (§ 9 / § 10 JuSchG)",
"objectives": [
"Altersgrenzen für Bier/Wein/Spirituosen sicher benennen",
"Ausnahme § 9 Abs. 2 (Personensorge) erklären",
"Testkauf-Situationen sauber handhaben"
],
"topics": ["§ 9 JuSchG", "§ 10 JuSchG", "Alkopops", "Testkauf", "Ausweiskontrolle"],
"difficulty": "einfach",
"source_heading": "Jugendschutz"
},
{
"id": "ifsg43",
"title": "Belehrung nach § 43 IfSG",
"objectives": [
"Erst- und Folgebelehrung unterscheiden",
"Meldepflichten bei Infektionen kennen",
"Frist-Grenzen im Anstellungsfall"
],
"topics": ["§ 43 IfSG", "Gesundheitszeugnis", "Erstbelehrung", "Folgebelehrung"],
"difficulty": "einfach",
"source_heading": "Infektionsschutzgesetz § 43"
},
{
"id": "lmhv-haccp",
"title": "LMHV + VO 852/2004 + HACCP",
"objectives": [
"Die 7 HACCP-Grundsätze aufzählen",
"Kühltemperatur-Grenzen (+4 °C, 18 °C)",
"Dokumentationspflicht erklären"
],
"topics": ["VO 852/2004", "LMHV § 4", "HACCP", "Kühlkette", "Reinigungsplan"],
"difficulty": "mittel",
"source_heading": "LMHV + HACCP"
},
{
"id": "konzession",
"title": "Konzessionen & Gestattung",
"objectives": [
"Gaststättenerlaubnis vs. Gestattung",
"§ 12 GastG bei Events",
"Pflichten der Schankkraft ohne Konzession"
],
"topics": ["GastG", "§ 12 GastG Gestattung", "Konzessionspflicht"],
"difficulty": "mittel",
"source_heading": "Gastgewerbeverordnung"
}
]
},
{
"id": "mixology",
"title": "2 · Mixology Basics",
"short": "Klassiker, Technik, Glaswahl",
"icon": "medal",
"color": "#ea580c",
"description": "IBA-Klassiker und das Handwerk der Bar — rühren, shaken, bauen, muddeln. Von Old Fashioned bis Aperol Spritz.",
"source_md": "mixology-grundlagen.md",
"modules": [
{
"id": "technik",
"title": "Grundtechniken (Rühren/Shaken/Build/Muddle)",
"objectives": [
"Die 5 Techniken den richtigen Drinks zuordnen",
"Gain-Verlust durch zu langes Shaken verstehen",
"Dry Shake bei Eiweißdrinks einsetzen"
],
"topics": ["Stirring", "Shaking", "Building", "Muddling", "Dry Shake"],
"difficulty": "einfach",
"source_heading": "Techniken"
},
{
"id": "klassiker",
"title": "Die 10 Unforgettables",
"objectives": [
"Rezepte für Old Fashioned, Negroni, Daiquiri sicher",
"Mojito, Margarita, Martini, Manhattan",
"Whisky Sour, Aperol Spritz, Gin Tonic"
],
"topics": ["Old Fashioned", "Negroni", "Daiquiri", "Mojito", "Margarita", "Martini"],
"difficulty": "mittel",
"source_heading": "Die Klassiker"
},
{
"id": "glas-garnitur",
"title": "Glaswahl & Garnituren",
"objectives": [
"Tumbler/Highball/Coupette richtig einsetzen",
"Zeste-Technik (Öl freisetzen)",
"Salzrand & Garnitur-Basics"
],
"topics": ["Tumbler", "Highball", "Coupette", "Zeste", "Salzrand"],
"difficulty": "einfach",
"source_heading": "Glaswahl"
},
{
"id": "masse",
"title": "Maß-Systeme (cl / ml / oz)",
"objectives": [
"cl-ml-oz schnell umrechnen",
"Jigger sicher anwenden",
"Freihand-Schütten vermeiden"
],
"topics": ["cl", "ml", "oz", "Jigger", "1 oz = 3 cl"],
"difficulty": "einfach",
"source_heading": "Maß-Systeme"
}
]
},
{
"id": "service",
"title": "3 · Service & Etikette",
"short": "Sequence, Reklamation, Zahlung",
"icon": "handshake",
"color": "#d97706",
"description": "Gastgeber sein: Sequence of Service, Bestellaufnahme, Reklamationshandling (LAST), Zahlung & Trinkgeld.",
"source_md": "service-etikette.md",
"modules": [
{
"id": "sequence",
"title": "Sequence of Service",
"objectives": [
"Die 10 Schritte vom Begrüßen bis zum Farewell",
"Check-Back-Timing (2-3 Min nach Speiseabgabe)",
"Gastrhythmus erkennen"
],
"topics": ["Greet", "Take Order", "Check-Back", "Farewell"],
"difficulty": "einfach",
"source_heading": "Sequence of Service"
},
{
"id": "reklamation",
"title": "Reklamation (LAST-Regel)",
"objectives": [
"Listen-Acknowledge-Solve-Thank anwenden",
"Entschädigung angemessen wählen",
"Eskalation zur Schichtleitung"
],
"topics": ["LAST", "Entschädigung", "Eskalation"],
"difficulty": "mittel",
"source_heading": "Reklamationsmanagement"
},
{
"id": "zahlung",
"title": "Zahlung, Trinkgeld, Bonpflicht",
"objectives": [
"Bonpflicht § 146a AO sicher umsetzen",
"Trinkgeld-Etikette (DE)",
"Split-Rechnung effizient"
],
"topics": ["§ 146a AO", "Trinkgeld", "Split-Rechnung", "Kartenzahlung"],
"difficulty": "einfach",
"source_heading": "Zahlungsabwicklung"
},
{
"id": "gast-konflikt",
"title": "Heikle Situationen",
"objectives": [
"Angetrunkenen Gast deeskalieren",
"Zechpreller richtig handhaben",
"Security/110 richtig einsetzen"
],
"topics": ["Deeskalation", "Zechprellerei § 263a", "Hausrecht"],
"difficulty": "mittel",
"source_heading": "Heikle Situationen"
}
]
},
{
"id": "event-tech",
"title": "4 · Veranstaltungstechnik",
"short": "DGUV V17, VStättVO, Rigging",
"icon": "shield",
"color": "#b45309",
"description": "Sicherheit im Event-Betrieb: DGUV V17/V18, Versammlungsstättenverordnung, Rigging-Basics, elektrische Sicherheit, Pyrotechnik.",
"source_md": "veranstaltungstechnik-basics.md",
"modules": [
{
"id": "dguv",
"title": "DGUV V17/V18 + Regel 115-002",
"objectives": [
"Anwendungsbereich V17 vs. V18",
"Pflicht-Unterweisung + Prüfung (jährlich)",
"Verantwortliche Person nach VStättVO"
],
"topics": ["DGUV V17", "DGUV V18", "Regel 115-002", "Verantwortliche Person"],
"difficulty": "mittel",
"source_heading": "DGUV V17 & V18"
},
{
"id": "vstaettvo",
"title": "VStättVO + Brandschutz",
"objectives": [
"Besucherzahl-Grenzen (> 200 indoor / > 1000 outdoor)",
"Fluchtweg-Regeln (max. 30 m)",
"Brandschutz auf Bühne (offenes Feuer grundsätzlich verboten)"
],
"topics": ["MVStättVO", "Fluchtweg", "Brandschau", "B1-Brandverhalten"],
"difficulty": "schwer",
"source_heading": "Versammlungsstättenverordnung"
},
{
"id": "rigging",
"title": "Rigging & Lastberechnung",
"objectives": [
"WLL vs. MBL unterscheiden",
"Sicherheitsfaktoren (5:1 / 7:1 / 10:1)",
"Secondary (Safety) Pflicht"
],
"topics": ["WLL", "MBL", "Secondary", "Kettenzug", "Traverse"],
"difficulty": "schwer",
"source_heading": "Rigging"
},
{
"id": "pyro-strom",
"title": "Pyrotechnik + Elektrik",
"objectives": [
"T1 vs. T2 Pyrotechnik (§ 20 / § 27 SprengG)",
"DGUV V3 Prüfung (Elektrik)",
"FI/RCD Pflicht im Bühnenumfeld"
],
"topics": ["SprengG", "Kat. T1/T2", "DGUV V3", "FI-Schutzschalter"],
"difficulty": "schwer",
"source_heading": "Pyrotechnik & Elektrische Sicherheit"
}
]
},
{
"id": "licht-ton",
"title": "5 · Licht & Ton",
"short": "DMX, Mischpult, 99 dB",
"icon": "medal",
"color": "#92400e",
"description": "Grundlagen der Licht- und Tontechnik: DMX-512, Moving Lights, Mischpult-Signal, FOH vs. Monitor, DIN 15905-5 Lärmschutz.",
"source_md": "licht-ton-basics.md",
"modules": [
{
"id": "dmx",
"title": "DMX-512 Grundlagen",
"objectives": [
"512 Kanäle, Startadresse, Daisy Chain",
"Terminator + XLR 110 Ω",
"Art-Net / sACN Überblick"
],
"topics": ["DMX-512", "Startadresse", "Universum", "Terminator", "sACN"],
"difficulty": "mittel",
"source_heading": "DMX-512"
},
{
"id": "scheinwerfer",
"title": "Scheinwerfer-Typen + 4-Licht-Konzept",
"objectives": [
"Spot / Wash / Beam unterscheiden",
"Key/Fill/Back/Kicker anwenden",
"LED vs. Entladungslampe"
],
"topics": ["Spot", "Wash", "Beam", "Key-Licht", "Fill"],
"difficulty": "mittel",
"source_heading": "Scheinwerfer-Typen"
},
{
"id": "mischpult",
"title": "Mischpult-Signal + Gain-Staging",
"objectives": [
"Gain-Stufe zuerst einstellen",
"EQ: schnitzen statt boosten",
"FOH vs. Monitor-Mix"
],
"topics": ["Gain", "EQ", "Aux-Send", "FOH", "Monitor"],
"difficulty": "mittel",
"source_heading": "Mischpult-Struktur"
},
{
"id": "din15905",
"title": "DIN 15905-5 Schallschutz",
"objectives": [
"99 dB(A) LAeq 30 min Grenze",
"135 dB(C) Peak-Grenze",
"Messpflicht ab 85 dB(A)"
],
"topics": ["DIN 15905-5", "LAeq", "LCpk", "Gehörschutz"],
"difficulty": "schwer",
"source_heading": "DIN 15905-5"
}
]
},
{
"id": "kasse-recht",
"title": "6 · Kassensystem-Recht",
"short": "KassenSichV, TSE, § 146a AO",
"icon": "award",
"color": "#fbbf24",
"description": "Das Kassensystem als rechtliche Infrastruktur: TSE-Pflicht, Bonausgabepflicht, DSFinV-K, Kassen-Nachschau.",
"source_md": "kassensystem-recht.md",
"modules": [
{
"id": "tse",
"title": "TSE-Pflicht + § 146a AO",
"objectives": [
"Was die TSE technisch leistet",
"Kassen-Meldepflicht (ELSTER seit 2025)",
"Unveränderbare Aufzeichnung"
],
"topics": ["TSE", "BSI TR-03153", "§ 146a AO", "ELSTER"],
"difficulty": "mittel",
"source_heading": "KassenSichV"
},
{
"id": "bon",
"title": "Bonpflicht + Pflichtinhalte",
"objectives": [
"Pflichtinhalte eines Bons",
"Digitaler Bon vs. Papier",
"Befreiungs-Ausnahme § 148 AO"
],
"topics": ["Belegausgabepflicht", "§ 6 KassenSichV", "QR-Code"],
"difficulty": "einfach",
"source_heading": "Bonpflicht"
},
{
"id": "kassenfuehrung",
"title": "Kassenführung im Tagesgeschäft",
"objectives": [
"Kassensturz + Z-Bon",
"Storno-Regeln dokumentieren",
"Trinkgeld separat"
],
"topics": ["Z-Bon", "Kassensturz", "Storno", "Trinkgeld"],
"difficulty": "mittel",
"source_heading": "Kassenführung"
},
{
"id": "nachschau",
"title": "Kassen-Nachschau (§ 146b AO)",
"objectives": [
"Was das Finanzamt darf",
"DSFinV-K-Export bereitstellen",
"Ruhig bleiben, Steuerberater rufen"
],
"topics": ["§ 146b AO", "DSFinV-K", "Prüfung", "Zuschätzung"],
"difficulty": "schwer",
"source_heading": "Kassen-Nachschau"
}
]
},
{
"id": "arbeitsschutz",
"title": "7 · Arbeitsschutz",
"short": "ArbZG, Unfälle, 1. Hilfe",
"icon": "clock",
"color": "#f97316",
"description": "Arbeitszeitgesetz, Mindestlohn, typische Unfallrisiken, Alkohol am Arbeitsplatz, Stress und die Erste-Hilfe-Kette.",
"source_md": "arbeitsschutz-gastro.md",
"modules": [
{
"id": "arbzg",
"title": "ArbZG in der Gastro",
"objectives": [
"Ruhezeit (11h, Gastro-Ausnahme 10h)",
"Nachtarbeit-Zuschlag 25 %",
"Pflicht-Arbeitszeiterfassung (BAG 2022)"
],
"topics": ["§ 3-5 ArbZG", "Ruhezeit", "Nachtarbeit", "Zeiterfassung"],
"difficulty": "mittel",
"source_heading": "Arbeitszeitgesetz"
},
{
"id": "mindestlohn",
"title": "Mindestlohn 2026 + Jugend/Mutter",
"objectives": [
"13,90 € / h 2026",
"Jugendarbeitsschutz < 18",
"Mutterschutz-Arbeitsverbote"
],
"topics": ["MiLoG", "JArbSchG", "MuSchG"],
"difficulty": "einfach",
"source_heading": "Mindestlohn 2026"
},
{
"id": "unfaelle",
"title": "Typische Unfälle + Prävention",
"objectives": [
"Top-5 Unfallarten in Gastro/Event",
"S2-Schuhe, Schnittschutz, Hitzeschutz",
"BG-Meldung > 3 Tage AU"
],
"topics": ["Stürze", "Schnittverletzung", "Verbrennung", "§ 193 SGB VII"],
"difficulty": "einfach",
"source_heading": "Unfallrisiken"
},
{
"id": "erste-hilfe",
"title": "Erste Hilfe + Notfallplan",
"objectives": [
"Notruf 112 mit W-Fragen",
"CPR 30:2 Rhythmus",
"Verbandbuch + Ersthelfer-Quote"
],
"topics": ["112", "CPR", "Verbandbuch", "DGUV V1 § 26"],
"difficulty": "einfach",
"source_heading": "Erste-Hilfe-Kette"
}
]
},
{
"id": "faq",
"title": "8 · FAQ Alltag",
"short": "20 typische Situationen",
"icon": "star",
"color": "#eab308",
"description": "Aus dem echten Bar-/Event-Alltag: 20 konkrete Situationen mit pragmatischer Handlungsanweisung.",
"source_md": "faq-frequent-situations.md",
"modules": [
{
"id": "faq-alkohol",
"title": "FAQ: Alkohol & Jugendschutz",
"objectives": [
"Minderjährige an der Theke",
"Angetrunkene Gäste",
"Fahrtüchtigkeit"
],
"topics": ["§ 9 JuSchG", "§ 323c StGB", "Hausrecht"],
"difficulty": "einfach",
"source_heading": "Alkohol & Jugendschutz"
},
{
"id": "faq-zahlung",
"title": "FAQ: Zahlung & Zechpreller",
"objectives": [
"Bei Zahlungsweigerung ruhig bleiben",
"Zechprellerei § 263a StGB",
"Kartenzahlung defekt → Bar"
],
"topics": ["§ 263a StGB", "Zechprellerei", "Rechnung"],
"difficulty": "mittel",
"source_heading": "Zahlung & Abrechnung"
},
{
"id": "faq-notfall",
"title": "FAQ: Notfall, Brand, Schlägerei",
"objectives": [
"Fettbrand: niemals Wasser",
"Schlägerei: 110, nicht dazwischen",
"Stromausfall: Notbeleuchtung"
],
"topics": ["CO₂-Löscher", "110", "112", "Notbeleuchtung"],
"difficulty": "mittel",
"source_heading": "Notfälle"
},
{
"id": "faq-event",
"title": "FAQ: Event-Technik-Pannen",
"objectives": [
"Pult-Crash kurz vor Türöffnung",
"Musiker will über 99 dB",
"Rigging-Unfall"
],
"topics": ["Reboot", "DIN 15905-5", "BG-Meldung"],
"difficulty": "schwer",
"source_heading": "Event-Technik"
}
]
}
],
"badges": [
{"id": "erste_schicht", "title": "Feuer frei", "icon": "flame", "description": "1. Quiz bestanden — Willkommen hinter der Theke."},
{"id": "cocktail_ninja", "title": "Cocktail-Ninja", "icon": "star", "description": "Mixology-Modul komplett (≥ 80 % in allen 4 Teilen)."},
{"id": "jugendschutz_watchdog", "title": "Jugendschutz-Wachhund", "icon": "shield", "description": "Alle Jugendschutz-Quizfragen korrekt."},
{"id": "dguv_profi", "title": "DGUV-Profi", "icon": "medal", "description": "Veranstaltungstechnik-Modul komplett."},
{"id": "gast_whisperer", "title": "Gast-Flüsterer", "icon": "handshake", "description": "Service-Etikette-Modul komplett."},
{"id": "kassen_pro", "title": "Kassen-Profi", "icon": "award", "description": "KassenSichV-Modul komplett."},
{"id": "all_rounder", "title": "Thekengeneral", "icon": "crown", "description": "Alle 8 Module erfolgreich abgeschlossen."},
{"id": "night_owl", "title": "Nachteule", "icon": "moon", "description": "Nach 22 Uhr gelernt — wie ein echter Barkeeper."}
],
"levels": [
{"min": 0, "title": "Barhilfe"},
{"min": 50, "title": "Azubi"},
{"min": 200, "title": "Shiftleader"},
{"min": 500, "title": "Barchef:in"},
{"min": 1250, "title": "Location-Manager:in"},
{"min": 2500, "title": "Betriebsleiter:in"},
{"min": 5000, "title": "Gastro-Unternehmer:in"}
]
}

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

@ -0,0 +1,4 @@
{ min: 0, title: 'Barhilfe' }, { min: 50, title: 'Azubi' },
{ min: 200, title: 'Shiftleader' }, { min: 500, title: 'Barchef:in' },
{ min: 1250, title: 'Location-Manager:in' }, { min: 2500, title: 'Betriebsleiter:in' },
{ min: 5000, title: 'Gastro-Unternehmer:in' }

25
src/welcome.html Normal file
View file

@ -0,0 +1,25 @@
<h2>Hi, ich bin Max.</h2>
<p>Ich bring dich durch die wichtigsten Basics für Bar-Crew + Bühne + Veranstaltungstechnik — <strong>rechtssicher</strong>, <strong>praxisnah</strong>, mit Quiz und Karten. Von Mixology über Kassenrecht (TSE/§ 146 AO) bis Licht-/Ton-Rigging und Veranstaltungs-Sicherheits-Konzept (VStättVO, §38 BImSchG). Sag mir, was bei dir ansteht — neuer Azubi am Tresen, Festival-Vorbereitung, FOH-Crew-Briefing.</p>
<div class="mode-grid">
<button class="mode-card" data-goto="chat">
<strong>Chat</strong>
<span>Frag mich alles zu Theke, Bühne, Recht.</span>
</button>
<button class="mode-card" data-goto="quiz">
<strong>Quiz</strong>
<span>Szenarien aus dem Bar-/Event-Alltag, mit XP.</span>
</button>
<button class="mode-card" data-goto="flash">
<strong>Karten</strong>
<span>Cocktails, Paragraphen, Begriffe — 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>Know-How</strong>
<span>8 Themenblöcke / 32 Module: Bar-Basics bis FAQ.</span>
</button>
</div>
<p style="font-size:.82rem;color:var(--text-mute)">Tipp: Chat zum Verstehen → Quiz zum Testen → Karten zum Merken. Fortschritt zeigt dir, wo du stehst.</p>

1754
www/app.js Normal file

File diff suppressed because it is too large Load diff

497
www/curricula.json Normal file
View file

@ -0,0 +1,497 @@
{
"version": "2026-04-24",
"updated": "2026-04-24",
"curricula": [
{
"id": "bar-basics",
"title": "1 · Bar-Basics Recht",
"short": "JuSchG, § 43 IfSG, LMHV, HACCP",
"icon": "shield",
"color": "#f59e0b",
"description": "Die rechtlichen Mindestpflichten hinter der Theke: Jugendschutz, Belehrung nach § 43 IfSG, Lebensmittelhygiene, HACCP-Grundsätze.",
"source_md": "bar-basics.md",
"modules": [
{
"id": "juschg",
"title": "Jugendschutz (§ 9 / § 10 JuSchG)",
"objectives": [
"Altersgrenzen für Bier/Wein/Spirituosen sicher benennen",
"Ausnahme § 9 Abs. 2 (Personensorge) erklären",
"Testkauf-Situationen sauber handhaben"
],
"topics": ["§ 9 JuSchG", "§ 10 JuSchG", "Alkopops", "Testkauf", "Ausweiskontrolle"],
"difficulty": "einfach",
"source_heading": "Jugendschutz"
},
{
"id": "ifsg43",
"title": "Belehrung nach § 43 IfSG",
"objectives": [
"Erst- und Folgebelehrung unterscheiden",
"Meldepflichten bei Infektionen kennen",
"Frist-Grenzen im Anstellungsfall"
],
"topics": ["§ 43 IfSG", "Gesundheitszeugnis", "Erstbelehrung", "Folgebelehrung"],
"difficulty": "einfach",
"source_heading": "Infektionsschutzgesetz § 43"
},
{
"id": "lmhv-haccp",
"title": "LMHV + VO 852/2004 + HACCP",
"objectives": [
"Die 7 HACCP-Grundsätze aufzählen",
"Kühltemperatur-Grenzen (+4 °C, 18 °C)",
"Dokumentationspflicht erklären"
],
"topics": ["VO 852/2004", "LMHV § 4", "HACCP", "Kühlkette", "Reinigungsplan"],
"difficulty": "mittel",
"source_heading": "LMHV + HACCP"
},
{
"id": "konzession",
"title": "Konzessionen & Gestattung",
"objectives": [
"Gaststättenerlaubnis vs. Gestattung",
"§ 12 GastG bei Events",
"Pflichten der Schankkraft ohne Konzession"
],
"topics": ["GastG", "§ 12 GastG Gestattung", "Konzessionspflicht"],
"difficulty": "mittel",
"source_heading": "Gastgewerbeverordnung"
}
]
},
{
"id": "mixology",
"title": "2 · Mixology Basics",
"short": "Klassiker, Technik, Glaswahl",
"icon": "medal",
"color": "#ea580c",
"description": "IBA-Klassiker und das Handwerk der Bar — rühren, shaken, bauen, muddeln. Von Old Fashioned bis Aperol Spritz.",
"source_md": "mixology-grundlagen.md",
"modules": [
{
"id": "technik",
"title": "Grundtechniken (Rühren/Shaken/Build/Muddle)",
"objectives": [
"Die 5 Techniken den richtigen Drinks zuordnen",
"Gain-Verlust durch zu langes Shaken verstehen",
"Dry Shake bei Eiweißdrinks einsetzen"
],
"topics": ["Stirring", "Shaking", "Building", "Muddling", "Dry Shake"],
"difficulty": "einfach",
"source_heading": "Techniken"
},
{
"id": "klassiker",
"title": "Die 10 Unforgettables",
"objectives": [
"Rezepte für Old Fashioned, Negroni, Daiquiri sicher",
"Mojito, Margarita, Martini, Manhattan",
"Whisky Sour, Aperol Spritz, Gin Tonic"
],
"topics": ["Old Fashioned", "Negroni", "Daiquiri", "Mojito", "Margarita", "Martini"],
"difficulty": "mittel",
"source_heading": "Die Klassiker"
},
{
"id": "glas-garnitur",
"title": "Glaswahl & Garnituren",
"objectives": [
"Tumbler/Highball/Coupette richtig einsetzen",
"Zeste-Technik (Öl freisetzen)",
"Salzrand & Garnitur-Basics"
],
"topics": ["Tumbler", "Highball", "Coupette", "Zeste", "Salzrand"],
"difficulty": "einfach",
"source_heading": "Glaswahl"
},
{
"id": "masse",
"title": "Maß-Systeme (cl / ml / oz)",
"objectives": [
"cl-ml-oz schnell umrechnen",
"Jigger sicher anwenden",
"Freihand-Schütten vermeiden"
],
"topics": ["cl", "ml", "oz", "Jigger", "1 oz = 3 cl"],
"difficulty": "einfach",
"source_heading": "Maß-Systeme"
}
]
},
{
"id": "service",
"title": "3 · Service & Etikette",
"short": "Sequence, Reklamation, Zahlung",
"icon": "handshake",
"color": "#d97706",
"description": "Gastgeber sein: Sequence of Service, Bestellaufnahme, Reklamationshandling (LAST), Zahlung & Trinkgeld.",
"source_md": "service-etikette.md",
"modules": [
{
"id": "sequence",
"title": "Sequence of Service",
"objectives": [
"Die 10 Schritte vom Begrüßen bis zum Farewell",
"Check-Back-Timing (2-3 Min nach Speiseabgabe)",
"Gastrhythmus erkennen"
],
"topics": ["Greet", "Take Order", "Check-Back", "Farewell"],
"difficulty": "einfach",
"source_heading": "Sequence of Service"
},
{
"id": "reklamation",
"title": "Reklamation (LAST-Regel)",
"objectives": [
"Listen-Acknowledge-Solve-Thank anwenden",
"Entschädigung angemessen wählen",
"Eskalation zur Schichtleitung"
],
"topics": ["LAST", "Entschädigung", "Eskalation"],
"difficulty": "mittel",
"source_heading": "Reklamationsmanagement"
},
{
"id": "zahlung",
"title": "Zahlung, Trinkgeld, Bonpflicht",
"objectives": [
"Bonpflicht § 146a AO sicher umsetzen",
"Trinkgeld-Etikette (DE)",
"Split-Rechnung effizient"
],
"topics": ["§ 146a AO", "Trinkgeld", "Split-Rechnung", "Kartenzahlung"],
"difficulty": "einfach",
"source_heading": "Zahlungsabwicklung"
},
{
"id": "gast-konflikt",
"title": "Heikle Situationen",
"objectives": [
"Angetrunkenen Gast deeskalieren",
"Zechpreller richtig handhaben",
"Security/110 richtig einsetzen"
],
"topics": ["Deeskalation", "Zechprellerei § 263a", "Hausrecht"],
"difficulty": "mittel",
"source_heading": "Heikle Situationen"
}
]
},
{
"id": "event-tech",
"title": "4 · Veranstaltungstechnik",
"short": "DGUV V17, VStättVO, Rigging",
"icon": "shield",
"color": "#b45309",
"description": "Sicherheit im Event-Betrieb: DGUV V17/V18, Versammlungsstättenverordnung, Rigging-Basics, elektrische Sicherheit, Pyrotechnik.",
"source_md": "veranstaltungstechnik-basics.md",
"modules": [
{
"id": "dguv",
"title": "DGUV V17/V18 + Regel 115-002",
"objectives": [
"Anwendungsbereich V17 vs. V18",
"Pflicht-Unterweisung + Prüfung (jährlich)",
"Verantwortliche Person nach VStättVO"
],
"topics": ["DGUV V17", "DGUV V18", "Regel 115-002", "Verantwortliche Person"],
"difficulty": "mittel",
"source_heading": "DGUV V17 & V18"
},
{
"id": "vstaettvo",
"title": "VStättVO + Brandschutz",
"objectives": [
"Besucherzahl-Grenzen (> 200 indoor / > 1000 outdoor)",
"Fluchtweg-Regeln (max. 30 m)",
"Brandschutz auf Bühne (offenes Feuer grundsätzlich verboten)"
],
"topics": ["MVStättVO", "Fluchtweg", "Brandschau", "B1-Brandverhalten"],
"difficulty": "schwer",
"source_heading": "Versammlungsstättenverordnung"
},
{
"id": "rigging",
"title": "Rigging & Lastberechnung",
"objectives": [
"WLL vs. MBL unterscheiden",
"Sicherheitsfaktoren (5:1 / 7:1 / 10:1)",
"Secondary (Safety) Pflicht"
],
"topics": ["WLL", "MBL", "Secondary", "Kettenzug", "Traverse"],
"difficulty": "schwer",
"source_heading": "Rigging"
},
{
"id": "pyro-strom",
"title": "Pyrotechnik + Elektrik",
"objectives": [
"T1 vs. T2 Pyrotechnik (§ 20 / § 27 SprengG)",
"DGUV V3 Prüfung (Elektrik)",
"FI/RCD Pflicht im Bühnenumfeld"
],
"topics": ["SprengG", "Kat. T1/T2", "DGUV V3", "FI-Schutzschalter"],
"difficulty": "schwer",
"source_heading": "Pyrotechnik & Elektrische Sicherheit"
}
]
},
{
"id": "licht-ton",
"title": "5 · Licht & Ton",
"short": "DMX, Mischpult, 99 dB",
"icon": "medal",
"color": "#92400e",
"description": "Grundlagen der Licht- und Tontechnik: DMX-512, Moving Lights, Mischpult-Signal, FOH vs. Monitor, DIN 15905-5 Lärmschutz.",
"source_md": "licht-ton-basics.md",
"modules": [
{
"id": "dmx",
"title": "DMX-512 Grundlagen",
"objectives": [
"512 Kanäle, Startadresse, Daisy Chain",
"Terminator + XLR 110 Ω",
"Art-Net / sACN Überblick"
],
"topics": ["DMX-512", "Startadresse", "Universum", "Terminator", "sACN"],
"difficulty": "mittel",
"source_heading": "DMX-512"
},
{
"id": "scheinwerfer",
"title": "Scheinwerfer-Typen + 4-Licht-Konzept",
"objectives": [
"Spot / Wash / Beam unterscheiden",
"Key/Fill/Back/Kicker anwenden",
"LED vs. Entladungslampe"
],
"topics": ["Spot", "Wash", "Beam", "Key-Licht", "Fill"],
"difficulty": "mittel",
"source_heading": "Scheinwerfer-Typen"
},
{
"id": "mischpult",
"title": "Mischpult-Signal + Gain-Staging",
"objectives": [
"Gain-Stufe zuerst einstellen",
"EQ: schnitzen statt boosten",
"FOH vs. Monitor-Mix"
],
"topics": ["Gain", "EQ", "Aux-Send", "FOH", "Monitor"],
"difficulty": "mittel",
"source_heading": "Mischpult-Struktur"
},
{
"id": "din15905",
"title": "DIN 15905-5 Schallschutz",
"objectives": [
"99 dB(A) LAeq 30 min Grenze",
"135 dB(C) Peak-Grenze",
"Messpflicht ab 85 dB(A)"
],
"topics": ["DIN 15905-5", "LAeq", "LCpk", "Gehörschutz"],
"difficulty": "schwer",
"source_heading": "DIN 15905-5"
}
]
},
{
"id": "kasse-recht",
"title": "6 · Kassensystem-Recht",
"short": "KassenSichV, TSE, § 146a AO",
"icon": "award",
"color": "#fbbf24",
"description": "Das Kassensystem als rechtliche Infrastruktur: TSE-Pflicht, Bonausgabepflicht, DSFinV-K, Kassen-Nachschau.",
"source_md": "kassensystem-recht.md",
"modules": [
{
"id": "tse",
"title": "TSE-Pflicht + § 146a AO",
"objectives": [
"Was die TSE technisch leistet",
"Kassen-Meldepflicht (ELSTER seit 2025)",
"Unveränderbare Aufzeichnung"
],
"topics": ["TSE", "BSI TR-03153", "§ 146a AO", "ELSTER"],
"difficulty": "mittel",
"source_heading": "KassenSichV"
},
{
"id": "bon",
"title": "Bonpflicht + Pflichtinhalte",
"objectives": [
"Pflichtinhalte eines Bons",
"Digitaler Bon vs. Papier",
"Befreiungs-Ausnahme § 148 AO"
],
"topics": ["Belegausgabepflicht", "§ 6 KassenSichV", "QR-Code"],
"difficulty": "einfach",
"source_heading": "Bonpflicht"
},
{
"id": "kassenfuehrung",
"title": "Kassenführung im Tagesgeschäft",
"objectives": [
"Kassensturz + Z-Bon",
"Storno-Regeln dokumentieren",
"Trinkgeld separat"
],
"topics": ["Z-Bon", "Kassensturz", "Storno", "Trinkgeld"],
"difficulty": "mittel",
"source_heading": "Kassenführung"
},
{
"id": "nachschau",
"title": "Kassen-Nachschau (§ 146b AO)",
"objectives": [
"Was das Finanzamt darf",
"DSFinV-K-Export bereitstellen",
"Ruhig bleiben, Steuerberater rufen"
],
"topics": ["§ 146b AO", "DSFinV-K", "Prüfung", "Zuschätzung"],
"difficulty": "schwer",
"source_heading": "Kassen-Nachschau"
}
]
},
{
"id": "arbeitsschutz",
"title": "7 · Arbeitsschutz",
"short": "ArbZG, Unfälle, 1. Hilfe",
"icon": "clock",
"color": "#f97316",
"description": "Arbeitszeitgesetz, Mindestlohn, typische Unfallrisiken, Alkohol am Arbeitsplatz, Stress und die Erste-Hilfe-Kette.",
"source_md": "arbeitsschutz-gastro.md",
"modules": [
{
"id": "arbzg",
"title": "ArbZG in der Gastro",
"objectives": [
"Ruhezeit (11h, Gastro-Ausnahme 10h)",
"Nachtarbeit-Zuschlag 25 %",
"Pflicht-Arbeitszeiterfassung (BAG 2022)"
],
"topics": ["§ 3-5 ArbZG", "Ruhezeit", "Nachtarbeit", "Zeiterfassung"],
"difficulty": "mittel",
"source_heading": "Arbeitszeitgesetz"
},
{
"id": "mindestlohn",
"title": "Mindestlohn 2026 + Jugend/Mutter",
"objectives": [
"13,90 € / h 2026",
"Jugendarbeitsschutz < 18",
"Mutterschutz-Arbeitsverbote"
],
"topics": ["MiLoG", "JArbSchG", "MuSchG"],
"difficulty": "einfach",
"source_heading": "Mindestlohn 2026"
},
{
"id": "unfaelle",
"title": "Typische Unfälle + Prävention",
"objectives": [
"Top-5 Unfallarten in Gastro/Event",
"S2-Schuhe, Schnittschutz, Hitzeschutz",
"BG-Meldung > 3 Tage AU"
],
"topics": ["Stürze", "Schnittverletzung", "Verbrennung", "§ 193 SGB VII"],
"difficulty": "einfach",
"source_heading": "Unfallrisiken"
},
{
"id": "erste-hilfe",
"title": "Erste Hilfe + Notfallplan",
"objectives": [
"Notruf 112 mit W-Fragen",
"CPR 30:2 Rhythmus",
"Verbandbuch + Ersthelfer-Quote"
],
"topics": ["112", "CPR", "Verbandbuch", "DGUV V1 § 26"],
"difficulty": "einfach",
"source_heading": "Erste-Hilfe-Kette"
}
]
},
{
"id": "faq",
"title": "8 · FAQ Alltag",
"short": "20 typische Situationen",
"icon": "star",
"color": "#eab308",
"description": "Aus dem echten Bar-/Event-Alltag: 20 konkrete Situationen mit pragmatischer Handlungsanweisung.",
"source_md": "faq-frequent-situations.md",
"modules": [
{
"id": "faq-alkohol",
"title": "FAQ: Alkohol & Jugendschutz",
"objectives": [
"Minderjährige an der Theke",
"Angetrunkene Gäste",
"Fahrtüchtigkeit"
],
"topics": ["§ 9 JuSchG", "§ 323c StGB", "Hausrecht"],
"difficulty": "einfach",
"source_heading": "Alkohol & Jugendschutz"
},
{
"id": "faq-zahlung",
"title": "FAQ: Zahlung & Zechpreller",
"objectives": [
"Bei Zahlungsweigerung ruhig bleiben",
"Zechprellerei § 263a StGB",
"Kartenzahlung defekt → Bar"
],
"topics": ["§ 263a StGB", "Zechprellerei", "Rechnung"],
"difficulty": "mittel",
"source_heading": "Zahlung & Abrechnung"
},
{
"id": "faq-notfall",
"title": "FAQ: Notfall, Brand, Schlägerei",
"objectives": [
"Fettbrand: niemals Wasser",
"Schlägerei: 110, nicht dazwischen",
"Stromausfall: Notbeleuchtung"
],
"topics": ["CO₂-Löscher", "110", "112", "Notbeleuchtung"],
"difficulty": "mittel",
"source_heading": "Notfälle"
},
{
"id": "faq-event",
"title": "FAQ: Event-Technik-Pannen",
"objectives": [
"Pult-Crash kurz vor Türöffnung",
"Musiker will über 99 dB",
"Rigging-Unfall"
],
"topics": ["Reboot", "DIN 15905-5", "BG-Meldung"],
"difficulty": "schwer",
"source_heading": "Event-Technik"
}
]
}
],
"badges": [
{"id": "erste_schicht", "title": "Feuer frei", "icon": "flame", "description": "1. Quiz bestanden — Willkommen hinter der Theke."},
{"id": "cocktail_ninja", "title": "Cocktail-Ninja", "icon": "star", "description": "Mixology-Modul komplett (≥ 80 % in allen 4 Teilen)."},
{"id": "jugendschutz_watchdog", "title": "Jugendschutz-Wachhund", "icon": "shield", "description": "Alle Jugendschutz-Quizfragen korrekt."},
{"id": "dguv_profi", "title": "DGUV-Profi", "icon": "medal", "description": "Veranstaltungstechnik-Modul komplett."},
{"id": "gast_whisperer", "title": "Gast-Flüsterer", "icon": "handshake", "description": "Service-Etikette-Modul komplett."},
{"id": "kassen_pro", "title": "Kassen-Profi", "icon": "award", "description": "KassenSichV-Modul komplett."},
{"id": "all_rounder", "title": "Thekengeneral", "icon": "crown", "description": "Alle 8 Module erfolgreich abgeschlossen."},
{"id": "night_owl", "title": "Nachteule", "icon": "moon", "description": "Nach 22 Uhr gelernt — wie ein echter Barkeeper."}
],
"levels": [
{"min": 0, "title": "Barhilfe"},
{"min": 50, "title": "Azubi"},
{"min": 200, "title": "Shiftleader"},
{"min": 500, "title": "Barchef:in"},
{"min": 1250, "title": "Location-Manager:in"},
{"min": 2500, "title": "Betriebsleiter:in"},
{"min": 5000, "title": "Gastro-Unternehmer:in"}
]
}

121
www/index.html Normal file
View file

@ -0,0 +1,121 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Max · Bar & Bühnen-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="Max — dein Bar & Bühnen-Coach. Crash-Kurs für Bar-Kräfte und Event-Crews — rechtssicher, praxisnah, Deutschland-legal. DSGVO-konform im Bunker.">
<link rel="stylesheet" href="styles.css">
<script>window.__MAX_KEY__ = 'qb_vdxwoq9mh6hy';</script>
</head>
<body>
<div class="app" role="application" aria-label="Max Bar und Bühnen-Coach">
<header class="topbar">
<div class="brand">
<span class="brand-icon" aria-hidden="true">M</span>
<span>Max <small>Bar &amp; Bühnen-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">
Know-How
<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 Max.</h2>
<p>Ich bring dich durch die wichtigsten Basics für Bar-Crew + Bühne + Veranstaltungstechnik — <strong>rechtssicher</strong>, <strong>praxisnah</strong>, mit Quiz und Karten. Von Mixology über Kassenrecht (TSE/§ 146 AO) bis Licht-/Ton-Rigging und Veranstaltungs-Sicherheits-Konzept (VStättVO, §38 BImSchG). Sag mir, was bei dir ansteht — neuer Azubi am Tresen, Festival-Vorbereitung, FOH-Crew-Briefing.</p>
<div class="mode-grid">
<button class="mode-card" data-goto="chat">
<strong>Chat</strong>
<span>Frag mich alles zu Theke, Bühne, Recht.</span>
</button>
<button class="mode-card" data-goto="quiz">
<strong>Quiz</strong>
<span>Szenarien aus dem Bar-/Event-Alltag, mit XP.</span>
</button>
<button class="mode-card" data-goto="flash">
<strong>Karten</strong>
<span>Cocktails, Paragraphen, Begriffe — 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>Know-How</strong>
<span>8 Themenblöcke / 32 Module: Bar-Basics bis FAQ.</span>
</button>
</div>
<p style="font-size:.82rem;color:var(--text-mute)">Tipp: Chat zum Verstehen → Quiz zum Testen → Karten zum Merken. Fortschritt zeigt dir, wo du stehst.</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>
<!-- CURRICULUM -->
<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 Max — 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