5073e7bcf497ffbcd3dfd980875c80aaff8eadd3
13
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5073e7bcf4 |
Jede Idee bekommt ihre eigene Seite mit der Unterhaltung aus dem Thread
Vorbild windrose.support: Klick auf eine Idee, und man sieht sie ganz — Stand, Begruendung, wer sie eingereicht hat, und darunter, was dazu geschrieben wurde. Der Unterschied bleibt, wo geschrieben wird. Die Beitraege sind aus dem Discord-Thread gespiegelt, nicht hier getippt. Deshalb fuehrt der einzige Knopf am Ende in den Thread und nicht in ein Formular. Ein zweiter Ort fuer dieselbe Unterhaltung waere genau das, was ich beim Konzept als das Falsche bezeichnet habe. Bisher wurde nur mitgezaehlt. Jetzt landen die Beitraege in einer eigenen Tabelle — mit Bearbeiten und Loeschen, sonst stuende auf der Webseite fuer immer, was in Discord laengst zurueckgenommen wurde. Reine Bild-Posts ohne Text bleiben draussen, die haetten hier nichts zu sagen. Der Kommentar-Zaehler wird jetzt aus der Tabelle gezaehlt statt in einer Spalte mitgefuehrt. Eine Wahrheit statt zwei, die auseinanderlaufen koennen — dieselbe Ueberlegung wie beim Zuspruch. Nebenbei geprueft, weil es haette schiefgehen koennen: /api/wishes/suche und /api/wishes/:id liegen auf derselben Ebene. Der Router bevorzugt die feste Route vor der mit Platzhalter — nachgestellt mit find-my-way, nicht aus dem Gedaechtnis behauptet. Geprueft: im Browser die Seite mit drei Beitraegen und die ohne (kein Thread, keine Begruendung, Hinweis statt Liste), der Weg von der Roadmap dorthin ohne Neuladen, Migration erneut durchgespielt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
1856a1ed83 |
Foren waehlbar, Emoji-Tafel repariert, Balken sagt seit wann er misst
Drei Dinge, die beim Ausprobieren aufgefallen sind. ## Foren standen nicht zur Auswahl Ein Forum-Kanal ist fuer discord.js nicht "textBased" — er hat keine Nachrichten, nur Beitraege. Die Kanal-Liste im Panel hat genau danach gefiltert, also tauchte das Forum nirgends auf, und beim Speichern haette dieselbe Pruefung es abgelehnt. Beides kennt jetzt Foren und Medien-Kanaele; in der Auswahl stehen sie mit 📋 statt # und dem Hinweis "Forum". Das erklaert auch das "Unknown Channel" beim Testen: eingestellt war noch der alte Kanal, und der neue liess sich gar nicht erst waehlen. ## Emoji-Tafel landete in der Nachbarspalte Die Config laeuft ab genug Breite zweispaltig — CSS `columns: 2`. In einem Mehrspalten-Layout zerreisst es absolut positionierte Kaesten: die Tafel wurde fragmentiert und ihr Inhalt in der anderen Spalte gezeichnet, waehrend beim Feld nur der leere Rahmen stehen blieb. Genau so sah es auch aus. Die Tafel haengt jetzt an <body> und wird per JS an den Knopf gerechnet, wie der Dialog auch. Sie klappt nach oben, wenn unten kein Platz ist, wandert beim Scrollen mit und bleibt beim Fenstergroesse-Aendern an ihrem Feld. ## Balken sagt jetzt, seit wann er misst Die Waechter-Balken sahen leer aus. Sind sie nicht: 545 Messpunkte, alle gruen — aber eben nur von heute, weil die Dienste gestern angelegt wurden. Sechs von sieben Tagen sind zu Recht grau, das sieht nur aus wie kaputt. Steht links jetzt "misst seit 01.08." statt stur "vor 7 Tagen", sobald die erste Messung deutlich spaeter liegt als der Anfang des Fensters. Bei vollem Verlauf bleibt es bei "vor 7 Tagen". Geprueft im Browser: Tafel an <body> und `position: fixed`, richtig positioniert und nach oben geklappt, alle sieben Gruppen und 127 Symbole in einem Stueck; Forum in der Auswahlliste mit Kennzeichnung; beide Beschriftungen des Balkens (angebrochener und voller Verlauf). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
edf8fa14c5 |
Ideen bekommen Bereiche und einen Thread zum Reden
Nach dem Vorbild von windrose.support: Bereiche zum Einsortieren, Sortierung nach Top / Bewegung / Neu, und eine Zahl daneben, wie viel darueber geredet wird. Der Unterschied zu so einem Dienst ist, wo geredet wird. Zu jedem Wunsch macht der Bot jetzt einen Thread unter dem Post auf. Der Kommentar-Zaehler auf der Roadmap zaehlt die Beitraege darin und verlinkt hinein — es gibt also einen Zaehler wie bei einem Ideen-Board, aber ohne ein zweites Kommentarsystem neben Discord zu stellen. Genau das hatte ich beim letzten Mal als das Falsche bezeichnet, und dabei bleibt es. Eingereicht wird jetzt auch ueber einen Aufruf-Post: /wunsch-setup postet ihn, und mit Bereichen wird daraus ein Auswahlmenue — erst wohin, dann das Formular. Ohne Bereiche bleibt es beim einen Knopf. Derselbe Aufbau wie bei den Ticket-Anliegen, bis hin zur Emoji-Pruefung, die ich mir dort schon geschrieben hatte. Das Anlegen selbst ist nach bot/wishes.js gewandert. /wunsch, der Knopf und die Webseite gehen jetzt denselben Weg — vorher hatte die Webseite ihr eigenes Embed zusammengebaut, das dem aus dem Befehl nur aehnlich sah und keinen Thread bekam. "Bewegung" sind die Stimmen der letzten sieben Tage. Die Rangliste allein zementiert alte Wuensche: was einmal oben steht, bleibt oben, egal ob noch jemand hinschaut. Sortiert wird auf dem Server, weil die Zeitstempel der Stimmen im Browser gar nicht ankommen. Bewusst nicht uebernommen: Gegenstimmen. Windrose hat sie, aber bei einer Community dieser Groesse laden sie zum Nachtreten ein und schrecken vom Einreichen ab — und eine Zahl, die aus zwei Richtungen kommt, sagt am Ende weniger als eine, die nur zaehlt, wer etwas will. Geprueft: Migration erneut durchgespielt (das Schema hat drei Spalten dazubekommen), Routen, SQL gegen das Schema, und im Browser alle drei Filterreihen einzeln und kombiniert, der Sortierwechsel, die Thread-Links und die Bereichs-Pflege im Panel. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fb61e7279d |
Wuensche bekommen einen Ausgang statt nur einer Punktzahl
Voting hatten wir. Was fehlte, war alles danach: ein Wunsch sammelte zwoelf Stimmen und dann passierte sichtbar nie wieder etwas damit. Genau das nennt der Artikel, der die Idee angestossen hat, "letting the board become a graveyard" — und das war der Zustand. Jeder Wunsch hat jetzt einen Stand: wird geprueft, geplant, in Arbeit, umgesetzt, nicht geplant — mit Begruendung. Die steht oeffentlich unter dem Wunsch auf der Roadmap und wird in den Discord-Post zurueckgeschrieben, wo abgestimmt wurde. Ein abgelehnter Wunsch mit einem Satz Begruendung ist mehr wert als einer, der ewig oben schwebt. Springt ein Wunsch auf "umgesetzt", bekommt jeder eine Direktnachricht, der dafuer gestimmt hat. Das ist der Punkt, an dem unser Aufbau einem fertigen Voting-Dienst ueberlegen ist: der Draht zu jedem Einzelnen ist ohnehin offen. ## Zwei Sachen, die kaputt waren Doppelt abstimmen ging. Der Zuspruch wurde von zwei Wegen hochgezaehlt — 👍 in Discord und der Web-Knopf — und nur der Web-Weg merkte sich, wer geklickt hat. Dieselbe Person zaehlte zweimal. Jetzt wird nicht mehr hochgezaehlt, sondern gezaehlt: eine Zeile je Person, egal woher der Klick kam. Der zusammengesetzte Schluessel schliesst den Fall aus, statt ihn nachtraeglich zu korrigieren. Die Discord-Nachrichten-ID war der Primaerschluessel. Damit konnte ein Wunsch nur existieren, solange seine Nachricht existiert, das Team konnte keinen von Hand eintragen, und zwei Doppler liessen sich nicht zusammenfuehren. Wuensche haben jetzt eine eigene ID; die Nachrichten-ID ist nur noch ein Verweis. Die Migration erhaelt den Zuspruch: was vom alten Punktestand nicht auf gespeicherte Web-Stimmen zurueckgeht, waren Reaktionen ohne Namen — die Zahl bleibt als Sockel stehen, weil rueckwirkend niemand mehr feststellen kann, wer das war. Durchgespielt gegen eine Datenbank im alten Aufbau: Punktestand erhalten, verwaiste Stimmen fallen raus, ein zweiter Start migriert nicht nochmal, und der Fall, in dem der alte Zaehler hinter den echten Stimmen zurueckhing, zaehlt jetzt richtig. ## Dazu Doppler zusammenfuehren: die Stimmen wandern zum Original, wer fuer beide gestimmt hat, zaehlt dort weiterhin einmal. Beim Tippen im Wunsch-Feld zeigt die Seite, was es schon gibt — ein Klick darauf stimmt mit, statt einen zweiten gleichen Wunsch anzulegen. Und die Liste laesst sich nach Stand filtern. Was ich bewusst nicht gebaut habe: Kommentare auf der Webseite. Jeder Wunsch ist schon eine Discord-Nachricht — die Diskussion gehoert in den Thread darunter und nicht in ein zweites System. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
e32152b5ac |
Eigener Herzschlag: der Bot kann jetzt auch ueber sich selbst Auskunft geben
Der Waechter prueft alles ausser sich selbst — ist der Bot weg, prueft niemand mehr, und hinterher sieht der Verlauf aus, als waere nie etwas gewesen. Im Dashboard stand deshalb nur "seit 12d 4h", also wie lange es diesmal gutgegangen ist. Was davor war, wusste niemand. Jetzt schreibt der Bot alle zwei Minuten eine Zeile: laeuft der Prozess, und steht die Verbindung zu Discord? Ein Bot, der laeuft aber nicht verbunden ist, ist fuer alle draussen genauso weg — deshalb zaehlt beides. Der Takt ist absichtlich nicht einstellbar. Ein spaeter geaenderter Abstand wuerde den alten Verlauf falsch aussehen lassen: wie viele Proben eine Stunde haette haben muessen, liesse sich rueckwirkend nicht mehr sagen. Ausgewertet wird vor allem die Abwesenheit. Fuer einen fremden Dienst heisst eine fehlende Stunde "niemand hat gemessen" und wird grau; beim Bot selbst ist genau das die Aussage — fehlende Stunden werden rot. Grau bleibt nur, was vor der allerersten Aufzeichnung liegt. Die angebrochene erste und die laufende letzte Stunde rechnen anteilig, sonst waeren sie dauerhaft gelb. Nebenbei mitgenommen: - Statusseite und die frei angelegten Seiten stehen jetzt in der Fusszeile beider Seiten — dort sucht man Rechtliches. Die Navigationsleiste zeigt weiterhin nur, was "im Menü" gesetzt hat; wer die Nutzungsbedingungen dort raus nimmt, hat sie trotzdem noch in der Fusszeile. - Die Config-Spalte hatte keine Obergrenze. min-width:0 allein reicht nicht, wenn ein Kind eine grosse Mindestbreite mitbringt — mit dem Balken wuchs sie auf 724 statt 335 px, und weil der Body waagerecht abschneidet, war der Ueberstand nicht scrollbar, sondern weg. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
3080f52e71 |
AutoMod sichtbar machen: Treffer ins Protokoll, Regeln ins Panel
Discords eigener Filter arbeitet serverseitig und ohne Latenz — daran ist nichts zu verbessern. Was fehlte, war die Sicht darauf: Treffer landeten nur in Discords eigenem Kanal, und die Regeln pflegte man in einer ganz anderen Oberflaeche als alles andere. Jetzt spiegelt der Bot jeden Treffer als Embed ins Mod-Log — mit Nutzer, Regel, Ausloeser, Massnahme, getroffenem Wort und gekuerztem Wortlaut, ohne Erwaehnungen, die den Kanal anpingen. Im Panel steht unter Support jede Regel mit Ausloeser, Massnahmen und der Zahl ausgenommener Rollen und Kanaele — letzteres oft der Grund, warum eine Regel scheinbar nicht greift. Schalten geht dort direkt. Das Bearbeiten der Wortlisten bleibt bewusst in Discord; dort ist es gut geloest, und ein zweiter Ort dafuer waere nur eine weitere Stelle, an der etwas auseinanderlaeuft. Dazu noetig: der Gateway-Intent AutoModerationExecution. Nicht privilegiert, aber Discord schickt die Ereignisse nur an Bots mit "Server verwalten" — fehlt das Recht, sagt das Panel es statt still leer zu bleiben. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c8b1f604f0 |
Umfragen: /umfrage als native Discord-Abstimmung
Bewusst Discords eigenes Poll-Objekt statt einer Nachbildung mit Knoepfen — Oberflaeche, Auszaehlen und Ergebnisanzeige macht Discord dann selbst, auch auf dem Handy. Wir bauen nur die Frage zusammen. Bis zu vier Antworten (Discord erlaubt zehn, vier halten den Befehl uebersichtlich), Laufzeit von einer Stunde bis einer Woche, Mehrfachauswahl optional. Rechte: ManageMessages. Zwei gleiche Antworten werden abgefangen. Discord stoert das nicht, aber abstimmen kann darauf niemand sinnvoll. Nicht zu verwechseln mit /wunsch: das sammelt Feature-Wuensche dauerhaft und zeigt sie auf der Roadmap. /umfrage ist die schnelle Frage zwischendurch und laeuft von selbst ab. Steht so auch als Kommentar im Befehl. Geprueft gegen die installierte discord.js-Fassung (14.27) statt gegen die Dokumentation: Feldnamen aus den Typdefinitionen gelesen, und die fertige Nutzlast durch discord.js' eigene Serialisierung gejagt. Kommt als poll_media / allow_multiselect / layout_type 1 raus, genau wie Discords API es erwartet. Dazu: 18 Befehle laden ohne Namenskollision, Befehl steht auf der oeffentlichen Liste in beiden Sprachen, Zahl auf der Produktseite von 17 auf 18. Nutzungsbedingungen als Entwurf unter docs/ — Text fuer den Seiten-Editor, keine Rechtsberatung. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
137452da11 |
Linked Roles: Rollen, die an geprueften Werten haengen
Neues Modul, standardmaessig aus. Ein Mitglied klickt in Discord auf "Rolle holen", landet auf /linked-roles, bestaetigt den OAuth-Dialog — und der Bot schiebt ihm drei Kennzahlen zu, die Discord dann gegen die Rollen-Einstellung prueft: level Zahl >= eingestelltem Wert dabei_seit Datum <= "vor X Tagen", also Mitglied seit mindestens X Tagen playtester Wahrheitswert Der Bot vergibt dabei keine Rollen. Er liefert nur die Zahlen; was daraus wird, entscheidet die Rollen-Einstellung im Server. Die Daten kommen aus dem, was ohnehin da ist: Level-Tabelle, Playtester-Liste, Discords Beitrittsdatum. Eigener OAuth-Weg statt /auth/login, weil die Berechtigungen andere sind — role_connections.write hat der normale Login nicht. Die Tokens werden gespeichert, und das ist keine Bequemlichkeit: ohne Refresh-Token bliebe jede Rolle auf dem Stand des Verknuepfungs-Tages stehen, ein Level-Up kaeme nie an. Discords eigene Anleitung sagt dasselbe. Der Umfang ist eng (nur identify + role_connections.write), beim Widerruf oder Entkoppeln fliegt der Datensatz sofort raus. Steht so auch als Kommentar an der Tabelle. Abgeglichen wird alle 6 Stunden, einstellbar. Dafuer kann everyTuned jetzt auch Stunden — und wirft bei einer unbekannten Einheit, statt den Abstand still um Faktor 60 oder 3600 danebenzulegen. Beim Bauen gefunden: moduleEnabled fehlte im Import von client.js. Der Bot waere beim ClientReady mit ReferenceError gestorben. Geprueft: alle drei Kennzahlen gegen Discords Formatgrenzen (Schluessel-Regex, Laengen, gueltige Typ-Codes), Modul- und Stellwert-Register, die Stunden-Umrechnung (6 h = 21600000 ms), Speichern und Loeschen einer Verknuepfung, dazu 186 SQL-Abfragen und alle Routen auf Rechtepruefung. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
55e9ef57e2 |
Oeffentliche Statusseite nach Statuspage-Vorbild
Neue Seite /status auf dem Hub: Gesamtlage als Banner, darunter die
freigegebenen Dienste mit 90-Tage-Balken, die Game-Server, und die
Stoerungs-Historie der letzten 90 Tage.
Die Adressliste ist von einer kommagetrennten Einstellung in eine Tabelle
gewandert. Jeder Dienst hat jetzt Namen, Gruppe und einen Schalter
"oeffentlich" — sonst stuende auf einer oeffentlichen Seite die nackte URL,
auch von internen Diensten. Die alte Liste wird beim ersten Start uebernommen,
bewusst als nicht oeffentlich: was dort auftaucht, soll eine Entscheidung sein
und nicht durch eine Migration passieren.
/api/status liefert nur freigegebene Dienste und dabei keine Adressen, nur
Namen. Auch die Stoerungs-Historie ist gefiltert — sonst verriete sie, was es
sonst noch gibt. Im Browser gegengeprueft: auf der ganzen Seite steht kein
einziges https://.
Stoerungen werden jetzt aufgezeichnet, nicht nur gemeldet: pro Adresse ein
offener Eintrag, bis es wieder laeuft. Beim Wiederkommen wird er geschlossen,
bevor die DM rausgeht — sonst bliebe er bei einem Sendefehler ewig offen.
Aufbewahrung von 7 auf 90 Tage. Der Balken kann jetzt zwei Aufloesungen:
168 Stunden fuers Panel ("was war letzte Nacht?") und 90 Tage fuer die
Statusseite ("wie zuverlaessig?"). Stuendlich ueber 90 Tage waeren ueber 2000
Striche und unlesbar.
Im Panel sind aus der reinen Anzeige Verwaltung geworden: anlegen, bearbeiten,
entfernen, freigeben — dazu die Stoerungsliste.
Beim Bauen gefunden: die Uebernahme der alten Liste stand mitten in db.js und
rief getSetting(), dessen prepared statement erst 300 Zeilen weiter unten
entsteht. Der Bot starb beim Start mit "Cannot access getSettingStmt before
initialization" — nachgewiesen, dann ans Dateiende verschoben.
Geprueft: 182 SQL-Abfragen gegen das Schema, alle schreibenden Routen bewacht,
Stoerungs-Logik durchgespielt (doppeltes Eroeffnen wird abgelehnt, Schliessen
ohne offene gibt null), und beide Seiten im Browser mit drei Diensten in allen
drei Zustaenden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
91397d8a44 |
Raid-Sperre von Hand setzen, aufheben oder nachsehen
Der fehlende Befehl zum Raid-Schutz. Drei Unterbefehle: status ist gerade gesperrt, und wie lange noch an jetzt sperren — fuer die Welle, die man kommen sieht aus sofort aufheben — fuer den Fehlalarm um drei Uhr nachts Rechte: ManageGuild, weil die Sperre genau das anfasst — Verifizierung und Invites. Antworten sind ephemeral. Die Sperr-Massnahmen sind in dichtmachen() herausgezogen, damit automatisch und von Hand denselben Weg nehmen und sich nicht auseinanderentwickeln. Die Meldung sagt jeweils dazu, wodurch sie ausgeloest wurde und wer es war. Ist der Raid-Schutz ausgeschaltet, verweist der Befehl aufs Panel statt stillschweigend nichts zu tun. Dazu: der Befehl steht auf der oeffentlichen Befehls-Seite, in beiden Sprachen, und die Zahl auf der Produktseite geht von 16 auf 17. Geprueft: 17 Befehle laden, keine doppelten Namen, Rechte-Bitmaske 32 (ManageGuild), alle neuen Exporte vorhanden, kein Sprachschluessel fehlt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
aef708c405 |
Raid-Schutz: erkennt Beitritts-Wellen und sperrt voruebergehend
Neues Modul anti_raid, standardmaessig AUS. Zaehlt Beitritte in einem Zeitfenster; reisst es, geht der Server dicht: Verifizierung auf Hoch, Einladungen gesperrt, DM an den Owner und Eintrag ins Protokoll. Bewusst zurueckhaltend — es wird niemand gekickt oder gebannt. Bei einem Fehlalarm, etwa nach einem Stream-Shoutout, waere ein Massenkick schlimmer als der Raid. Beide Massnahmen sind reversibel und treffen niemanden, der schon drin ist. Der Sperrzustand liegt in den Einstellungen, nicht nur im Speicher: startet der Bot mitten in einer Sperre neu, waere der Timer sonst weg und der Server bliebe fuer immer dicht. Beim Start wird die Restzeit abgesessen oder, wenn laengst abgelaufen, sofort aufgehoben. Drei Werte im Panel: Schwelle (8), Fenster (20 s), Sperrdauer (15 min). disableInvites() gibt es erst ab discord.js 14.4 und nur mit ManageGuild — beides wird geprueft, statt im Ernstfall einen Fehler zu werfen. Die Fenster-Logik ist als reine Funktion herausgezogen und mit neun Faellen geprueft: langsame Beitritte loesen nicht aus, die Welle schon, der Rand des Zeitfensters zaehlt nicht mehr mit, und nach Ruhe faengt das Fenster von vorn. Offen: ein Befehl zum sofortigen Aufheben. Bis dahin laeuft die Sperre aus oder man setzt die Verifizierung in Discord selbst zurueck. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
1e2d295665 |
Erreichbarkeits-Balken auf der Server-Seite
Ein Strich pro Stunde ueber 7 Tage, gruen/gelb/rot je nachdem, ob in der Stunde alle, ein Teil oder keine Messung erreichbar war. Die Daten lagen laengst da: player_history haelt 7 Tage vor, die API schnitt aber auf 24 Stunden ab. Statt Rohdaten (ueber eine Woche rund 5000 Zeilen pro Server) fasst uptimeBuckets() in SQL stundenweise zusammen — hoechstens 168 Zeilen. - Stunden ohne Messung werden als Luecke gezeichnet, nicht als "online". Sonst saehe eine Bot-Auszeit aus wie ein einwandfrei laufender Server. - Die alte 24h-Uptime-Zahl neben dem Peak ist raus: zweimal dieselbe Groesse ueber verschiedene Zeitraeume verwirrt nur. - Tooltip zeigt Ortszeit. Die Eimer werden in UTC abgeglichen (SQLite rechnet so), angezeigt wird lokal — sonst stuende dort eine Stunde, die niemand wiedererkennt. Zwei Fehler beim Bauen gefunden und behoben: - .srv-card ist ein Grid-Item mit min-width:auto und wuchs durch die 168 Striche auf 724 statt 335 px, die Karte sprengte auf dem Handy das Raster. - "Uhr" stand hart deutsch im Tooltip. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
5360c8229f |
Englisch als zweite Sprache fuer die oeffentlichen Seiten
Hub und Bot-Produktseite lassen sich jetzt auf Englisch umstellen. Die Wahl haengt am Browser (Deutsch nur, wenn der Browser es will) und bleibt im localStorage stehen. - src/i18n.jsx: Context mit t(), tOr(), Datums- und Zahlenformat der Sprache. Keine Bibliothek, die Woerterbuecher werden mitgebaut — kein Nachlade-Blitzer. - Platzhalter im %s-Stil, dieselbe Schreibweise wie in den Bot-Texten. - Umschalter in der Navigation, zusaetzlich im Schubladen-Menue: .auth ist auf schmalen Schirmen ausgeblendet, sonst waere der Wechsel dort unerreichbar. - Datums- und Zahlenformat folgen mit (31.07.2026 / 31/07/2026, 45.231 / 45,231). - Die Funktionsliste kommt weiter deutsch vom Server; englische Modulnamen liegen unter feat.<id> im Woerterbuch. Fehlt einer, bleibt der Servertext stehen — ein neues Modul verschwindet nie von der Seite. Das Config-Panel und die Discord-Texte bleiben deutsch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |