awareness-coach/www/index.html

494 lines
21 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Ava · Awareness & Club-Manager-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="Ava — Awareness- und Club-Manager-Coach. Policy, Incident-Response, Haftung, Safer Spaces. Läuft im deutschen Bunker.">
<link rel="stylesheet" href="styles.css">
<script>window.__AVA_KEY__ = 'qb_cbfx31vpj6z5'; window.__WELCOME_VERSION__ = 2;</script>
</head>
<body>
<div class="app" role="application" aria-label="Ava Awareness-Coach">
<header class="topbar">
<div class="brand">
<span class="brand-icon" aria-hidden="true">A</span>
<span>Ava <small>Awareness & Club-Manager-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">
Flashcards
<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">
Policy-Bibliothek
<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">
<style>
/* Ava — Welcome polish (scoped to .welcome, only this bot) */
#welcome-screen.welcome {
display: block;
text-align: left;
padding: 0 !important;
min-height: auto !important;
max-width: 920px;
margin: 0 auto;
}
#welcome-screen.welcome > h2,
#welcome-screen.welcome > p {
display: none; /* hide default */
}
.ava-hero {
position: relative;
border-radius: 20px;
padding: 2.2rem 2rem 1.9rem;
margin: .25rem 0 1.4rem;
background:
radial-gradient(1200px 240px at 0% 0%, rgba(124,58,237,0.32), transparent 60%),
radial-gradient(900px 200px at 100% 100%, rgba(245,158,11,0.18), transparent 60%),
linear-gradient(160deg, #14101e 0%, #0d0a17 60%, #0a0a0f 100%);
border: 1px solid rgba(255,255,255,0.06);
overflow: hidden;
isolation: isolate;
}
.ava-hero::before {
content: "";
position: absolute; inset: 0;
background-image: radial-gradient(rgba(255,255,255,0.06) 1px, transparent 1px);
background-size: 3px 3px;
opacity: .25;
pointer-events: none;
mask-image: linear-gradient(180deg, rgba(0,0,0,.6), transparent 70%);
-webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,.6), transparent 70%);
}
.ava-hero::after {
content: "";
position: absolute;
top: -40%; right: -20%;
width: 480px; height: 480px;
background: radial-gradient(closest-side, rgba(168,85,247,0.22), transparent 70%);
filter: blur(8px);
pointer-events: none;
z-index: 0;
}
.ava-hero > * { position: relative; z-index: 1; }
.ava-eyebrow {
display: inline-flex;
align-items: center;
gap: .5rem;
font-size: .72rem;
letter-spacing: .12em;
text-transform: uppercase;
color: #cbb8ff;
background: rgba(124,58,237,0.12);
border: 1px solid rgba(124,58,237,0.32);
padding: .28rem .65rem;
border-radius: 999px;
font-weight: 600;
}
.ava-eyebrow .dot {
width: 6px; height: 6px; border-radius: 50%;
background: #a855f7;
box-shadow: 0 0 10px #a855f7;
}
.ava-title {
margin: .85rem 0 .35rem;
font-size: clamp(1.55rem, 3vw, 2.05rem);
letter-spacing: -0.025em;
line-height: 1.15;
font-weight: 800;
background: linear-gradient(120deg, #f5f3ff 0%, #c4b5fd 45%, #fcd34d 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.ava-sub {
color: #c8c5d4;
font-size: 1rem;
line-height: 1.55;
margin: 0 0 1.1rem;
max-width: 60ch;
}
.ava-sub strong { color: #ede9fe; font-weight: 600; }
.ava-trust {
display: flex;
flex-wrap: wrap;
gap: .55rem;
margin-top: .25rem;
}
.ava-trust .badge {
display: inline-flex;
align-items: center;
gap: .45rem;
padding: .35rem .7rem;
background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.1);
border-radius: 999px;
font-size: .76rem;
color: #d4d2de;
}
.ava-trust .badge svg {
width: 14px; height: 14px; flex: none;
color: #a855f7;
}
.ava-trust .badge.amber svg { color: #fbbf24; }
.ava-trust .badge.teal svg { color: #5eead4; }
/* Use-case grid */
.ava-uc {
margin-bottom: 1.5rem;
}
.ava-section-head {
display: flex;
align-items: baseline;
justify-content: space-between;
margin: .25rem .25rem .65rem;
gap: 1rem;
}
.ava-section-head h3 {
font-size: .92rem;
letter-spacing: -.005em;
font-weight: 600;
color: #ede9fe;
margin: 0;
}
.ava-section-head .hint {
font-size: .76rem;
color: var(--text-mute);
}
.uc-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: .65rem;
}
.uc-card {
position: relative;
text-align: left;
background: linear-gradient(165deg, #16131f 0%, #110f19 100%);
border: 1px solid rgba(255,255,255,0.07);
border-radius: 14px;
padding: .95rem 1rem 1rem;
cursor: pointer;
font-family: inherit;
color: inherit;
transition: transform .18s ease, border-color .18s ease, background .18s ease;
overflow: hidden;
}
.uc-card::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(135deg, rgba(124,58,237,0.0), rgba(245,158,11,0.0));
opacity: 0;
transition: opacity .2s ease;
pointer-events: none;
}
.uc-card:hover {
transform: translateY(-2px);
border-color: rgba(124,58,237,0.45);
background: linear-gradient(165deg, #1c1729 0%, #16131f 100%);
}
.uc-card:hover::before { opacity: 1; background: linear-gradient(135deg, rgba(124,58,237,0.12), rgba(245,158,11,0.05)); }
.uc-card:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.uc-icon {
width: 34px; height: 34px;
display: grid; place-items: center;
border-radius: 10px;
background: linear-gradient(140deg, rgba(124,58,237,0.18), rgba(245,158,11,0.10));
border: 1px solid rgba(124,58,237,0.32);
color: #ddd6fe;
margin-bottom: .65rem;
}
.uc-icon svg { width: 18px; height: 18px; }
.uc-card.amber .uc-icon { background: linear-gradient(140deg, rgba(245,158,11,0.22), rgba(124,58,237,0.10)); border-color: rgba(245,158,11,0.32); color: #fde68a; }
.uc-card.teal .uc-icon { background: linear-gradient(140deg, rgba(94,234,212,0.18), rgba(124,58,237,0.10)); border-color: rgba(94,234,212,0.32); color: #99f6e4; }
.uc-card.rose .uc-icon { background: linear-gradient(140deg, rgba(244,114,182,0.16), rgba(124,58,237,0.10)); border-color: rgba(244,114,182,0.30); color: #fbcfe8; }
.uc-card h4 {
margin: 0 0 .25rem;
font-size: .94rem;
letter-spacing: -.01em;
font-weight: 600;
color: #f1f0f5;
}
.uc-card p {
margin: 0;
font-size: .8rem;
line-height: 1.45;
color: var(--text-dim);
}
.uc-card .uc-tag {
display: inline-block;
margin-top: .55rem;
font-size: .68rem;
letter-spacing: .04em;
text-transform: uppercase;
color: #a78bfa;
font-weight: 600;
}
.uc-card.amber .uc-tag { color: #fbbf24; }
.uc-card.teal .uc-tag { color: #5eead4; }
.uc-card.rose .uc-tag { color: #f9a8d4; }
/* Compact mode-row (the old big mode-cards become a thin strip) */
.ava-modes { margin-top: .5rem; }
.mode-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: .5rem;
}
.mode-pill {
display: flex;
align-items: center;
gap: .55rem;
padding: .65rem .8rem;
background: rgba(255,255,255,0.03);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 10px;
cursor: pointer;
font-family: inherit;
color: inherit;
text-align: left;
font-size: .85rem;
transition: background .15s, border-color .15s, transform .15s;
}
.mode-pill:hover {
background: rgba(124,58,237,0.10);
border-color: rgba(124,58,237,0.4);
transform: translateY(-1px);
}
.mode-pill svg { width: 16px; height: 16px; color: #a78bfa; flex: none; }
.mode-pill .label { font-weight: 600; color: #f1f0f5; }
.mode-pill .sub { color: var(--text-mute); font-size: .72rem; display: block; margin-top: 1px; }
.ava-foot {
margin-top: 1.4rem;
padding-top: .9rem;
border-top: 1px dashed rgba(255,255,255,0.08);
font-size: .76rem;
color: var(--text-mute);
line-height: 1.55;
}
.ava-foot strong { color: #ddd6fe; font-weight: 600; }
@media (max-width: 640px) {
.ava-hero { padding: 1.6rem 1.25rem 1.4rem; border-radius: 16px; }
.ava-title { font-size: 1.45rem; }
.ava-sub { font-size: .92rem; }
.uc-grid { grid-template-columns: 1fr; }
.mode-row { grid-template-columns: repeat(2, 1fr); }
}
</style>
<section class="ava-hero" aria-labelledby="ava-hero-title">
<span class="ava-eyebrow"><span class="dot"></span>Sovereign AI · Bunker Schleswig-Holstein</span>
<h2 id="ava-hero-title" class="ava-title">Hi, ich bin Ava — Awareness &amp; Club-Manager-Coach.</h2>
<p class="ava-sub">
Ich helfe dir, deine Location <strong>sicher, inklusiv und rechtsfest</strong> zu führen — von der Awareness-Policy über Incident-Response bis zu Veranstalter-Haftung und Krisen-PR. <strong>Safer Spaces entstehen durch klare Strukturen, nicht durch Zufall.</strong>
</p>
<div class="ava-trust">
<span class="badge">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
Inferenz im deutschen Bunker
</span>
<span class="badge teal">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 12l2 2 4-4"/><circle cx="12" cy="12" r="10"/></svg>
DSGVO &amp; AI-Act-konform
</span>
<span class="badge amber">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/></svg>
45-Sekunden-Spawn pro Org
</span>
</div>
</section>
<section class="ava-uc" aria-labelledby="ava-uc-head">
<div class="ava-section-head">
<h3 id="ava-uc-head">Konkret unterstütze ich dich bei …</h3>
<span class="hint">Klick → Frage landet im Chat</span>
</div>
<div class="uc-grid">
<button class="uc-card" data-prompt="Wir planen ein Festival in 4 Monaten (ca. 3.000 Gäste, 2 Tage). Welche Awareness-Bausteine brauchen wir minimum, und in welcher Reihenfolge sollten wir sie aufsetzen?">
<div class="uc-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 21V8l9-5 9 5v13"/><path d="M9 21V12h6v9"/></svg>
</div>
<h4>Festival-Saison vorbereiten</h4>
<p>Awareness-Konzept, Team-Recruiting, Briefing-Pakete und Sicherheits-Schnittstellen vor Saisonstart.</p>
<span class="uc-tag">Veranstalter</span>
</button>
<button class="uc-card rose" data-prompt="Heute Nacht hat eine Gästin sexualisierte Belästigung an der Bar gemeldet. Awareness-Team hat erstes Gespräch geführt. Was sind die nächsten 24 Stunden — Doku, Personalentscheidung, Kommunikation?">
<div class="uc-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 9v4"/><path d="M12 17h.01"/><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/></svg>
</div>
<h4>Vorfall passiert — was jetzt?</h4>
<p>Incident-Response Schritt für Schritt: Erstgespräch, Doku, Polizei?, Personal, Kommunikation in den nächsten 24 h.</p>
<span class="uc-tag">Akut</span>
</button>
<button class="uc-card" data-prompt="Ich eröffne in 6 Wochen einen Club. Wie schreibe ich eine AGG-konforme Hausordnung und eine sinnvolle Türkommunikation, ohne mich als Veranstalter angreifbar zu machen?">
<div class="uc-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="9" y1="13" x2="15" y2="13"/><line x1="9" y1="17" x2="15" y2="17"/></svg>
</div>
<h4>Hausordnung &amp; Türpolitik</h4>
<p>AGG-konforme Hausordnung, Türkommunikation, Aushänge — mit konkreten Formulierungen statt Goodwill.</p>
<span class="uc-tag">Eröffnung</span>
</button>
<button class="uc-card amber" data-prompt="Auf Instagram macht seit 3 Stunden ein Vorwurf gegen unsere Location die Runde — angeblich übergriffiges Türpersonal. Wie reagieren wir die nächsten 48 Stunden, was sagen wir öffentlich, was intern?">
<div class="uc-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 11l18-5v12L3 14v-3z"/><path d="M11.6 16.8a3 3 0 1 1-5.8-1.6"/></svg>
</div>
<h4>Krisenkommunikation</h4>
<p>Statement nach Vorfall, Social-Media-Reaktion, Crew-Kommunikation — was sagen, was lassen, in welcher Reihenfolge.</p>
<span class="uc-tag">Öffentlichkeit</span>
</button>
<button class="uc-card" data-prompt="Welche rechtlichen Pflichten habe ich als Veranstalter:in bei sicherheitsrelevanten Vorfällen — was muss ich melden, dokumentieren, versichern? Inklusive Verkehrssicherungspflicht und Anzeigepflichten.">
<div class="uc-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6l9-3 9 3v6c0 5-4 8-9 10-5-2-9-5-9-10V6z"/><path d="M9 12l2 2 4-4"/></svg>
</div>
<h4>Recht &amp; Haftung</h4>
<p>Veranstalter-Pflichten, Anzeige- und Doku-Pflichten, Versicherungs-Logik — mit § und Praxis-Bezug.</p>
<span class="uc-tag">Recht</span>
</button>
<button class="uc-card teal" data-prompt="Wir wollen ein Awareness-Team aufbauen — 6-8 Leute, Schichtbetrieb. Wo fangen wir an: Recruiting-Kanäle, Auswahl, Schulung, Schichtmodell, Vergütung, rechtlicher Status?">
<div class="uc-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
</div>
<h4>Awareness-Team aufbauen</h4>
<p>Recruiting-Kanäle, Auswahl, Schulung, Schichtmodell, Vergütung — von 0 auf einsatzfähig in 8 Wochen.</p>
<span class="uc-tag">Personal</span>
</button>
<button class="uc-card" data-prompt="Zwischen Awareness-Team und Security gibt es ständig Reibung — Security will durchgreifen, Awareness will hören. Wie strukturiere ich Joint-Briefings und kläre Mandate, ohne dass ein Team das andere übergeht?">
<div class="uc-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>
</div>
<h4>Konflikt im Team</h4>
<p>Awareness ↔ Security, Schichtleiter-Streit, Mitarbeiter-Trennung — Eskalations- und Gesprächsstruktur.</p>
<span class="uc-tag">Führung</span>
</button>
<button class="uc-card amber" data-prompt="Wie gehe ich pragmatisch mit Drogenkonsum am Tresen und im Backstage um — ohne Rechtsbruch und ohne die Branchenrealität zu ignorieren? Inklusive Notfall-Kette, Tür-Politik und Awareness-Schnittstelle.">
<div class="uc-icon">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 8v4l3 2"/></svg>
</div>
<h4>Harm Reduction</h4>
<p>Drogenkonsum in der Realität: Notfall-Kette, Türentscheidungen, Awareness-Schnittstelle — ohne § zu verletzen.</p>
<span class="uc-tag">Pragmatik</span>
</button>
</div>
</section>
<section class="ava-modes" aria-labelledby="ava-modes-head">
<div class="ava-section-head">
<h3 id="ava-modes-head">Oder direkt in einen Modus springen:</h3>
<span class="hint">Tabs ⌃1⌃5</span>
</div>
<div class="mode-row">
<button class="mode-pill" data-goto="chat">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
<span><span class="label">Chat</span><span class="sub">Frei fragen</span></span>
</button>
<button class="mode-pill" data-goto="quiz">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><path d="M12 17h.01"/><circle cx="12" cy="12" r="10"/></svg>
<span><span class="label">Quiz</span><span class="sub">Szenarien · 16 Module</span></span>
</button>
<button class="mode-pill" data-goto="flash">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M3 10h18"/></svg>
<span><span class="label">Flashcards</span><span class="sub">Spaced-Repetition</span></span>
</button>
<button class="mode-pill" data-goto="progress">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
<span><span class="label">Fortschritt</span><span class="sub">XP · Streaks · Badges</span></span>
</button>
<button class="mode-pill" data-goto="curriculum">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
<span><span class="label">Bibliothek</span><span class="sub">8 Curricula · 16 Module</span></span>
</button>
</div>
</section>
<p class="ava-foot">
<strong>Wie ich arbeite:</strong> Chat zum Verstehen → Quiz zum Testen → Flashcards zum Merken → Case-Requests im Chat für Rollenspiele auf Führungsebene. Quellen sind kuratiert (Clubcommission, Awareness-Akademie, AGG, BGB, StGB, OWiG); ich erfinde keine Paragraphen — wenn ich unsicher bin, sag ich's.
</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 Ava — 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>