Files
d4rkbot/docs/redesign/D4RKBOT-Funktionen-neu.dc.html
D4rkst3randClaude Opus 5 0d7628f14e
Deploy / check (push) Canceled after 0s
Deploy / deploy (push) Canceled after 0s
Den Entwurf und das Logo-Original einsortieren
Drei Dateien lagen unversioniert im Wurzelverzeichnis herum. Alle drei
gehoeren ins Repo, nur nicht dorthin:

  logo.png                        -> docs/brand/logo.png
  ChatGPT Image 23. Juni 2025 ... -> docs/brand/studie-kopf-2025-06.png
  design_handoff_redesign/        -> docs/redesign/

logo.png ist NICHT irgendein Logo, sondern das Original, von dem
docs/brand/README.md die ganze Zeit spricht: "ein einziges Original, 2048x2048
mit Transparenz". Nachgerechnet statt geraten -- auf den Inhalt beschnitten
ergibt es 1986x1963, exakt die Masse von lockup.png. Es lag also die Quelle
der Marke unversioniert daneben.

Dabei aufgefallen und in der README vermerkt, nicht repariert: build.py liest
das Original ueber einen festen Pfad ausserhalb des Repos
(QUELLE = A:/Users/DAR/logo.png). Jetzt sind das zwei Kopien, die
auseinanderlaufen koennen. Umstellen kann nur, wer weiss, welche der beiden
gepflegt wird.

Das zweite Bild ist eine frueherere Kopf-Studie und nicht die Vorlage der
heutigen Marke -- andere Zeichnung, flacher, ohne Fell und Schulter. Sie wird
nirgends benutzt und liegt als Herkunft.

Vom Entwurfs-Paket ist der assets/-Ordner entfallen: er enthielt Kopien von
mark.png und lockup.png, die zwei Verzeichnisse weiter im Original liegen. Die
.dc.html-Referenzen zeigen jetzt auf ../brand/ und stellen das Logo weiter
dar, statt mit kaputten Bildern zurueckzubleiben. Der Kopf der README sagt
ausserdem, dass der Entwurf umgesetzt ist und wo bewusst abgewichen wurde --
sonst liest sich das Dokument in einem Jahr wie eine offene Aufgabe.

Dazu eine Zeile, die seit dem Redesign nicht mehr stimmte: build.py bezeichnet
(10, 10, 10) als "--bg der Marke". Das ist seit gestern #131316. Wirkt erst,
wenn jemand build.py laufen laesst -- die erzeugten Icons in frontend/public/
tragen bis dahin den alten Grund. Neu bauen konnte ich sie hier nicht, es gibt
weder Python noch Pillow auf dieser Maschine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 15:19:49 +02:00

195 lines
20 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="./support.js"></script>
</head>
<body>
<x-dc>
<helmet>
<link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
html{color-scheme:dark}
body{background:#131316;color:#ececee;font-family:'Chakra Petch',sans-serif;font-size:16px;line-height:1.55;overflow-x:hidden;min-height:100vh}
a{color:inherit;text-decoration:none}
a:hover{color:#ffb340}
button{font-family:inherit;cursor:pointer}
::selection{background:rgba(255,154,31,.35);color:#131316}
@keyframes riseIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
</style>
</helmet>
<div style="min-height:100vh;display:flex;flex-direction:column;position:relative">
<div style="position:fixed;inset:0;pointer-events:none;background:radial-gradient(900px 500px at 78% -10%,rgba(240,120,0,.12),transparent 60%)"></div>
<header style="position:sticky;top:0;z-index:100;display:flex;align-items:center;gap:2rem;padding:.85rem 2.5rem;background:rgba(19,19,22,.88);backdrop-filter:blur(12px);border-bottom:1px solid rgba(255,255,255,.08)">
<a href="#" style="display:inline-flex;align-items:center;gap:.65rem;font-weight:700;font-size:1.12rem;letter-spacing:.06em;color:#ececee">
<img src="../brand/mark.png" alt="" style="width:34px;height:34px;object-fit:contain">
D4RKBOT<span style="color:#ff9a1f">_</span></a>
<nav style="display:flex;gap:1.8rem;flex:1;align-items:center;font-family:'IBM Plex Mono',monospace;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase">
<a href="#" style="color:#ffb340;border-bottom:2px solid #ff9a1f;padding-bottom:.2rem">Funktionen</a>
<a href="#" style="color:#9a9aa3" style-hover="color:#ffb340">Befehle</a>
<a href="#" style="color:#9a9aa3" style-hover="color:#ffb340">Community</a>
</nav>
<span style="font-family:'IBM Plex Mono',monospace;font-size:.64rem;letter-spacing:.14em;color:#66666e">DE / EN</span>
<a href="#" style="font-family:'IBM Plex Mono',monospace;font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:#131316;background:linear-gradient(135deg,#ffb340,#f07800);padding:.55rem 1.3rem;clip-path:polygon(8px 0,100% 0,100% calc(100% - 8px),calc(100% - 8px) 100%,0 100%,0 8px);font-weight:500">Anmelden</a>
</header>
<main style="flex:1;position:relative">
<section style="max-width:1160px;margin:0 auto;padding:4.5rem 2.5rem 2.5rem;animation:riseIn .45s ease both">
<div style="display:inline-flex;align-items:center;gap:.5rem;font-family:'IBM Plex Mono',monospace;font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:#ffb340;border:1px solid rgba(255,154,31,.4);padding:.35rem .8rem;clip-path:polygon(6px 0,100% 0,100% calc(100% - 6px),calc(100% - 6px) 100%,0 100%,0 6px)">Alles drin, nichts hinter einer Paywall</div>
<h1 style="font-size:3.6rem;font-weight:700;line-height:1.02;text-transform:uppercase;margin:1.1rem 0 .8rem">Funk<span style="background:linear-gradient(135deg,#ffb340,#f07800);-webkit-background-clip:text;background-clip:text;color:transparent">tionen</span></h1>
<p style="font-size:1.05rem;color:#9a9aa3;max-width:560px;line-height:1.65">47 Funktionen — jede einzeln ein- und ausschaltbar, jede im Browser einstellbar.</p>
</section>
<section style="max-width:1160px;margin:0 auto;padding:1rem 2.5rem 5rem">
<sc-for list="{{ groups }}" as="g" hint-placeholder-count="6">
<div style="margin-bottom:2.8rem">
<div style="display:flex;align-items:center;gap:1rem;margin-bottom:1.2rem">
<span style="width:22px;height:3px;background:linear-gradient(90deg,#ffb340,#f07800)"></span>
<h2 style="font-size:1.35rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em">{{ g.label }}</h2>
<span style="flex:1;height:1px;background:linear-gradient(90deg,rgba(255,255,255,.15),transparent)"></span>
<span style="font-family:'IBM Plex Mono',monospace;font-size:.62rem;letter-spacing:.12em;color:#66666e">{{ g.count }}</span>
</div>
<div style="display:grid;gap:1rem;grid-template-columns:repeat(3,1fr)">
<sc-for list="{{ g.items }}" as="f" hint-placeholder-count="6">
<div style="background:#1b1b20;border:1px solid rgba(255,255,255,.08);padding:1.2rem 1.3rem;clip-path:polygon(12px 0,100% 0,100% calc(100% - 12px),calc(100% - 12px) 100%,0 100%,0 12px);display:flex;flex-direction:column;gap:.4rem" style-hover="border-color:rgba(255,154,31,.5);background:#1f1f25;transform:translateY(-3px)">
<div style="display:flex;align-items:center;gap:.65rem">
<span style="display:inline-grid;place-items:center;width:32px;height:32px;background:rgba(255,154,31,.1);border:1px solid rgba(255,154,31,.3);color:#ffb340;clip-path:polygon(6px 0,100% 0,100% calc(100% - 6px),calc(100% - 6px) 100%,0 100%,0 6px)"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" dangerouslySetInnerHTML="{{ f.svg }}"></svg></span>
<span style="font-weight:600;font-size:.98rem">{{ f.name }}</span>
</div>
<p style="color:#9a9aa3;font-size:.85rem;line-height:1.55;margin:0">{{ f.desc }}</p>
</div>
</sc-for>
</div>
</div>
</sc-for>
<div style="border-top:1px solid rgba(255,255,255,.08);padding-top:1.8rem">
<p style="color:#9a9aa3;font-size:.95rem;line-height:1.65;max-width:640px;margin:0 0 1.4rem">Gebaut, weil drei Bots mit je eigenem Abo für eine Community weder übersichtlich noch günstig sind. Der Quelltext liegt offen, der Betrieb kostet einen Container.</p>
<div style="display:flex;gap:1rem;flex-wrap:wrap">
<a href="#" style="display:inline-flex;align-items:center;gap:.5rem;font-family:'IBM Plex Mono',monospace;font-size:.78rem;letter-spacing:.12em;text-transform:uppercase;color:#131316;background:linear-gradient(135deg,#ffb340,#f07800);padding:.8rem 1.6rem;font-weight:500;clip-path:polygon(10px 0,100% 0,100% calc(100% - 10px),calc(100% - 10px) 100%,0 100%,0 10px);box-shadow:0 0 30px rgba(240,120,0,.3)">Befehle ansehen →</a>
<a href="#" style="display:inline-flex;align-items:center;gap:.5rem;font-family:'IBM Plex Mono',monospace;font-size:.78rem;letter-spacing:.12em;text-transform:uppercase;color:#c9c9cf;border:1px solid rgba(255,255,255,.18);padding:.8rem 1.6rem;clip-path:polygon(10px 0,100% 0,100% calc(100% - 10px),calc(100% - 10px) 100%,0 100%,0 10px)" style-hover="background:rgba(255,255,255,.06);color:#ffb340">Zur Übersicht</a>
</div>
</div>
</section>
</main>
<footer style="border-top:1px solid rgba(255,255,255,.08);padding:1.4rem 2.5rem;display:flex;align-items:center;gap:1.2rem;font-family:'IBM Plex Mono',monospace;font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;color:#9a9aa3">
<span style="display:inline-flex;align-items:center;gap:.5rem;font-weight:700;color:#ececee;font-family:'Chakra Petch',sans-serif"><img src="../brand/mark.png" alt="" style="width:20px;height:20px;object-fit:contain">D4RKBOT<span style="color:#ff9a1f">_</span></span>
<a href="#" style-hover="color:#ffb340">Quellcode</a><a href="#" style-hover="color:#ffb340">Status</a>
<span style="margin-left:auto;display:flex;gap:1.2rem"><a href="#" style-hover="color:#ffb340">Impressum</a><a href="#" style-hover="color:#ffb340">Datenschutz</a></span>
</footer>
</div>
</x-dc>
<script type="text/x-dc" data-dc-script>
class Component extends DCLogic {
renderVals() {
const P = {
file: '<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/>',
terminal: '<polyline points="4 17 10 11 4 5"/><line x1="12" x2="20" y1="19" y2="19"/>',
rocket: '<path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/><path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/>',
activity: '<path d="M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2"/>',
message: '<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>',
play: '<polygon points="6 3 20 12 6 21 6 3"/>',
trend: '<polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/>',
star: '<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>',
star: '<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>',
image: '<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/>',
thumbs: '<path d="M7 10v12"/><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/>',
sparkles: '<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/>',
gift: '<rect x="3" y="8" width="18" height="4" rx="1"/><path d="M12 8v13"/><path d="M19 12v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-7"/><path d="M7.5 8a2.5 2.5 0 0 1 0-5A4.8 8 0 0 1 12 8a4.8 8 0 0 1 4.5-5 2.5 2.5 0 0 1 0 5"/>',
cake: '<path d="M20 21v-8a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v8"/><path d="M4 16s.5-1 2-1 2.5 2 4 2 2.5-2 4-2 2.5 2 4 2 2-1 2-1"/><path d="M2 21h20"/><path d="M7 8v3"/><path d="M12 8v3"/><path d="M17 8v3"/>',
calendar: '<path d="M8 2v4"/><path d="M16 2v4"/><rect width="18" height="18" x="3" y="4" rx="2"/><path d="M3 10h18"/>',
game: '<line x1="6" x2="10" y1="11" y2="11"/><line x1="8" x2="8" y1="9" y2="13"/><line x1="15" x2="15.01" y1="12" y2="12"/><line x1="18" x2="18.01" y1="10" y2="10"/><path d="M17.32 5H6.68a4 4 0 0 0-3.978 3.59c-.006.052-.01.101-.017.152C2.604 9.416 2 14.456 2 16a3 3 0 0 0 3 3c1 0 1.5-.5 2-1l1.414-1.414A2 2 0 0 1 9.828 16h4.344a2 2 0 0 1 1.414.586L17 18c.5.5 1 1 2 1a3 3 0 0 0 3-3c0-1.545-.604-6.584-.685-7.258-.007-.05-.011-.1-.017-.151A4 4 0 0 0 17.32 5z"/>',
key: '<path d="m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4"/><path d="m21 2-9.6 9.6"/><circle cx="7.5" cy="15.5" r="5.5"/>',
shield: '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>',
lock: '<rect width="18" height="11" x="3" y="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/>',
bot: '<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>',
archive: '<rect width="20" height="5" x="2" y="3" rx="1"/><path d="M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8"/><path d="M10 12h4"/>',
mail: '<rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/>',
ticket: '<path d="M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z"/><path d="M13 5v2"/><path d="M13 17v2"/><path d="M13 11v2"/>',
wand: '<path d="m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72Z"/><path d="m14 7 3 3"/><path d="M5 6v4"/><path d="M19 14v4"/><path d="M10 2v2"/>',
usercog: '<circle cx="18" cy="15" r="3"/><circle cx="9" cy="7" r="4"/><path d="M10 15H6a4 4 0 0 0-4 4v2"/><path d="m21.7 16.4-.9-.3"/><path d="m15.2 13.9-.9-.3"/><path d="m16.6 18.7.3-.9"/><path d="m19.1 12.2.3-.9"/><path d="m19.6 18.7-.4-1"/><path d="m16.8 12.3-.4-1"/><path d="m14.3 16.6 1-.4"/><path d="m20.7 13.8 1-.4"/>',
refresh: '<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/>',
warning: '<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/>',
server: '<rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><line x1="6" x2="6.01" y1="6" y2="6"/><line x1="6" x2="6.01" y1="18" y2="18"/>',
monitor: '<rect width="20" height="14" x="2" y="3" rx="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/>',
mic: '<path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" x2="12" y1="19" y2="22"/>',
zap: '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>',
clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
send: '<path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/>',
tag: '<path d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z"/><circle cx="7.5" cy="7.5" r=".5" fill="currentColor"/>',
db: '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/>',
pkg: '<path d="m7.5 4.27 9 5.15"/><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="m3.3 7 8.7 5 8.7-5"/><path d="M12 22V12"/>',
link: '<path d="M9 17H7A5 5 0 0 1 7 7h2"/><path d="M15 7h2a5 5 0 1 1 0 10h-2"/><line x1="8" x2="16" y1="12" y2="12"/>',
palette: '<circle cx="13.5" cy="6.5" r=".5"/><circle cx="17.5" cy="10.5" r=".5"/><circle cx="8.5" cy="7.5" r=".5"/><circle cx="6.5" cy="12.5" r=".5"/><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 0 1 1.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z"/>',
};
const m = (icon, name, desc) => ({ svg: { __html: P[icon] }, name, desc });
const g = (label, items) => ({ label, count: items.length + ' MODULE', items });
return {
groups: [
g('Inhalte & Feeds', [
m('file', 'Devlogs', 'Entwicklungs-Berichte als gebrandetes Embed posten und durchsuchbar archivieren.'),
m('terminal', 'Commit-Feed', 'Pushes aus Gitea landen als Embed im Kanal. Archiviert wird immer.'),
m('rocket', 'Release-Ankündigungen', 'Neue Releases werden angekündigt und landen im Changelog.'),
m('activity', 'Wochen-Rückblick', 'Sonntags um 20 Uhr eine Zusammenfassung der Woche.'),
m('message', 'Devlog-Threads', 'Unter jedem Devlog entsteht ein Diskussions-Thread.'),
m('play', 'Twitch & YouTube', 'Meldet Livestreams und neue Videos.'),
]),
g('Community', [
m('trend', 'Level-System', 'XP fürs Mitreden, Rollen-Belohnungen und öffentliche Bestenliste.'),
m('star', 'Starboard', 'Nachrichten mit genug Sternen landen in einem Best-of-Kanal.'),
m('image', 'Screenshot-Galerie', 'Bilder aus einem Kanal erscheinen in der öffentlichen Galerie.'),
m('thumbs', 'Feature-Wünsche', 'Wünsche einreichen und abstimmen — im Discord und auf der Roadmap.'),
m('thumbs', 'Umfragen', 'Schnelle Abstimmungen als native Discord-Umfrage — /umfrage.'),
m('sparkles', 'Radio', 'Webradio im Sprachkanal — /radio öffnet die Sender-Auswahl.'),
m('gift', 'Verlosungen', 'Teilnahme per Knopf, automatische Ziehung, Neuauslosung möglich.'),
m('cake', 'Geburtstage', 'Gratulation am großen Tag, optional mit Tages-Rolle.'),
m('calendar', 'Event-Ankündigungen', 'Neue Discord-Events werden angekündigt und erscheinen auf der Events-Seite.'),
m('game', 'Playtester-Programm', 'Bewerbungs-Knopf, Rolle und Teilnehmerliste.'),
m('key', 'Alpha-Keys', 'Schlüssel-Pool mit Verteilung per Direktnachricht.'),
m('shield', 'Rollen-Menüs', 'Selbstbedienungs-Rollen per Knopf — im Discord und im Profil.'),
m('file', 'Bewerbungen', 'Formulare als Eingabefenster, Prüfung mit Annehmen/Ablehnen.'),
m('link', 'Verknüpfte Rollen', 'Rollen an geprüften Werten — Level, Playtester, Mitgliedschaft.'),
]),
g('Moderation & Support', [
m('shield', 'Moderation', 'Verwarnen, Auszeiten, Aufräumen — mit Verlauf und Protokoll.'),
m('bot', 'AutoMod-Protokoll', 'Treffer von Discords Filter landen im Protokoll, Regeln sind schaltbar.'),
m('lock', 'Raid-Schutz', 'Erkennt Beitritts-Wellen und macht den Server vorübergehend dicht.'),
m('archive', 'Protokoll', 'Gelöschte und bearbeitete Nachrichten, Beitritte, Namens- und Rollenwechsel.'),
m('mail', 'Modmail', 'Direktnachrichten an den Bot landen als Thread beim Team.'),
m('ticket', 'Tickets', 'Private Threads per Knopf, beim Schließen ein Gesprächsprotokoll.'),
m('wand', 'Willkommens-Karten', 'Begrüßung neuer Mitglieder mit gerendertem Bild.'),
m('usercog', 'Auto-Rolle', 'Neue Mitglieder bekommen automatisch eine Startrolle.'),
m('refresh', 'Rollen merken', 'Wer zurückkommt, bekommt seine Rollen wieder.'),
m('warning', 'Fehlermeldungen', 'Meldungen werden zu Issues im Repository, mit Rückmeldung.'),
]),
g('Gaming', [
m('server', 'Game-Server-Monitor', 'Live-Status der Game-Server mit Verlauf und Ausfall-Alarm.'),
m('sparkles', 'LS — Höfe & Preise', 'Besitzkarte, Preiskurven übers Jahr und je Hof ein Embed mit Land und Fuhrpark.'),
]),
g('Server & Technik', [
m('monitor', 'Erreichbarkeits-Wächter', 'Prüft hinterlegte Adressen und meldet Ausfälle per Direktnachricht.'),
m('mic', 'Temporäre Sprachkanäle', 'Beitritt zum Hub erzeugt einen eigenen Kanal mit Bedienfeld.'),
m('zap', 'Auto-Antworten', 'Der Bot antwortet auf hinterlegte Schlüsselwörter.'),
m('clock', 'Erinnerungen', 'Mitglieder lassen sich per Direktnachricht erinnern.'),
m('send', 'Geplante Beiträge', 'Nachrichten zu festen Zeiten, einmalig oder wiederkehrend.'),
m('tag', 'Textbausteine', 'Gespeicherte Texte per Befehl abrufen.'),
m('db', 'Datenbank-Sicherung', 'Nächtliche Sicherung mit Aufbewahrung über 14 Tage.'),
m('pkg', 'Repository-Sicherung', 'Alle Gitea-Repositories als Bundle sichern.'),
m('lock', 'Login nur für Mitglieder', 'Nur wer auf dem Discord-Server ist, kann sich im Web anmelden.'),
]),
g('Drumherum', [
m('palette', 'Webinterface im eigenen Look', 'Alles im Browser einstellbar — keine Konfigurationsdatei, kein Neustart.'),
m('message', 'Texte selbst schreiben', 'Alles, was der Bot schreibt, lässt sich im Panel ändern — mit Platzhaltern.'),
m('key', 'API & Single Sign-On', 'Eigene Skripte posten über die API v1 mit Bearer-Schlüsseln.'),
m('file', 'Eigene Seiten', 'Regeln, Über uns, FAQ — in Markdown, mit einem Klick veröffentlicht.'),
m('usercog', 'Rechte fürs Team', 'Gezielter Zugriff auf einzelne Bereiche, alles im Protokoll.'),
m('server', 'Läuft überall', 'Node und SQLite in einem Container, ein Volume für die Daten.'),
]),
],
};
}
}
</script>
</body>
</html>