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:
commit
ab94f4a7e9
16 changed files with 4143 additions and 0 deletions
7
.dockerignore
Normal file
7
.dockerignore
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
bot.json
|
||||
src/
|
||||
docker-compose.yml
|
||||
*.md
|
||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
.DS_Store
|
||||
*.log
|
||||
*.tmp
|
||||
node_modules/
|
||||
13
Dockerfile
Normal file
13
Dockerfile
Normal 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
67
README.md
Normal 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
14
bot.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"slug": "bar-coach",
|
||||
"name": "Max",
|
||||
"title": "Bar & Bühnen-Coach",
|
||||
"tagline": "Bar & 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
20
docker-compose.yml
Normal 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
27
nginx.conf
Normal 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
23
src/check-badges.js
Normal 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
32
src/config.yaml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
slug: bar-coach
|
||||
bot_name: Max
|
||||
bot_title: "Bar & Bühnen-Coach"
|
||||
brand_letter: M
|
||||
title: "Max · Bar & Bühnen-Coach"
|
||||
tagline: "Bar und Bühnen-Coach"
|
||||
tagline_short: "Bar & 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
497
src/curricula.json
Normal 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
4
src/levels-fallback.js
Normal 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
25
src/welcome.html
Normal 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
1754
www/app.js
Normal file
File diff suppressed because it is too large
Load diff
497
www/curricula.json
Normal file
497
www/curricula.json
Normal 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
121
www/index.html
Normal 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 & 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> · 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
1038
www/styles.css
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue