Rebrand application as MetalCircle

This commit is contained in:
kai
2026-08-27 18:20:40 +02:00
parent eb71ea5a0e
commit 94e14ad3e8
83 changed files with 2561 additions and 51 deletions
+3 -2
View File
@@ -2,9 +2,10 @@
<summary>☠ {{ user.display_name }}{% if user.notification_count %} <span class="metal-notification" title="{{ user.notification_count }} neue Nachricht(en) oder Anfrage(n)" aria-label="Neue Benachrichtigungen">🤘<b>{{ user.notification_count }}</b></span>{% endif %}</summary>
<div class="user-menu-panel">
<a href="/profile">Mein Profil</a>
<a href="/messages">Nachrichten{% if user.unread_message_count %} <span class="menu-count">{{ user.unread_message_count }}</span>{% endif %}</a>
{% if user.event_invitation_count %}<a href="/#event-invitations">Veranstaltungseinladungen <span class="menu-count">{{ user.event_invitation_count }}</span></a>{% endif %}
<a href="/messages">Nachrichten{% if user.notification_count %} <span class="metal-notification" title="Neue Nachrichten oder Anfragen" aria-label="Neue Nachrichten oder Anfragen">🤘<b>{{ user.notification_count }}</b></span>{% endif %}</a>
{% if user.is_admin %}<a href="/admin">⚙️ Verwaltung</a>{% endif %}
<a href="/datenschutz">Datenschutz</a>
<a href="/impressum">Impressum</a>
<form method="post" action="/logout">
<button type="submit">Abmelden</button>
</form>
+2 -2
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html><html lang="de"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Account-Link · Pingu Concerts</title><link rel="stylesheet" href="/static/css/style.css"></head><body>
<header><div class="header-inner"><a href="/" class="logo">🎸 Pingu <span>Concerts</span></a>{% include '_user_menu.html' %}</div></header>
<!DOCTYPE html><html lang="de"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Account-Link · MetalCircle</title><link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png"><link rel="stylesheet" href="/static/css/style.css"></head><body>
<header><div class="header-inner"><a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a>{% include '_user_menu.html' %}</div></header>
<main><div class="page-title"><h1>Passwort zurücksetzen</h1><p>Reset-Link für @{{ target_username }} · {{ target_email }}</p></div>
<section class="admin-section"><p>Diesen persönlichen Link sicher an den User senden. Er ist zwei Stunden gültig und nur einmal verwendbar.</p><label class="invite-link" style="display:block;overflow-wrap:anywhere">{{ account_url }}</label><p><a class="button button-secondary" href="/admin/users">Zurück</a></p></section></main></body></html>
+3 -2
View File
@@ -3,7 +3,8 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Patch-Bilder · Pingu Concerts</title>
<title>Patch-Bilder · MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link rel="stylesheet" href="/static/css/style.css">
<style>
.patch-admin-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
@@ -15,7 +16,7 @@
</style>
</head>
<body>
<header><div class="header-inner"><a href="/" class="logo">🎸 Pingu <span>Concerts</span></a>{% include '_user_menu.html' %}</div></header>
<header><div class="header-inner"><a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a>{% include '_user_menu.html' %}</div></header>
<main>
<div class="page-title"><h1>🧵 Patch-Bilder</h1><p>Grafiken für die Patches auf der virtuellen Kutte verwalten.</p></div>
{% set admin_section = 'patches' %}{% include '_admin_nav.html' %}
+3 -2
View File
@@ -3,7 +3,8 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Benutzerverwaltung · Pingu Concerts</title>
<title>Benutzerverwaltung · MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link rel="stylesheet" href="/static/css/style.css">
<style>
.invite-link { display: block; margin-top: 14px; padding: 12px; overflow-wrap: anywhere; background: #0f1420; border: 1px solid var(--border); border-radius: 9px; color: #c4b5fd; }
@@ -17,7 +18,7 @@
</style>
</head>
<body>
<header><div class="header-inner"><a href="/" class="logo">🎸 Pingu <span>Concerts</span></a>{% include '_user_menu.html' %}</div></header>
<header><div class="header-inner"><a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a>{% include '_user_menu.html' %}</div></header>
<main>
<div class="page-title"><h1>⚙️ Verwaltung</h1><p>Benutzerkonten und Einladungen verwalten.</p></div>
{% set admin_section = 'users' %}{% include '_admin_nav.html' %}
+3 -2
View File
@@ -3,7 +3,8 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Veranstaltungsorte · Pingu Concerts</title>
<title>Veranstaltungsorte · MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link rel="stylesheet" href="/static/css/style.css">
<style>
.venue-fields { display: grid; grid-template-columns: 2fr 2fr .8fr 1.4fr 1.2fr; gap: 8px; }
@@ -29,7 +30,7 @@
</style>
</head>
<body>
<header><div class="header-inner"><a href="/" class="logo">🎸 Pingu <span>Concerts</span></a>{% include '_user_menu.html' %}</div></header>
<header><div class="header-inner"><a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a>{% include '_user_menu.html' %}</div></header>
<main>
<div class="page-title"><h1>📍 Veranstaltungsorte</h1><p>Orte korrigieren, bestätigen, zusammenführen oder entfernen.</p></div>
{% set admin_section = 'venues' %}{% include '_admin_nav.html' %}
+2 -1
View File
@@ -10,7 +10,8 @@
content="width=device-width, initial-scale=1.0"
>
<title>{{ concert.artist }} | Pingu Concerts</title>
<title>{{ concert.artist }} | MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link
rel="stylesheet"
+27
View File
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="de">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Datenschutz · MetalCircle</title><link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png"><link rel="stylesheet" href="/static/css/style.css"></head>
<body>
<header><div class="header-inner"><a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a></div></header>
<main>
<div class="page-title"><h1>Datenschutz</h1><p>Hinweise zur Verarbeitung deiner Daten</p></div>
<section class="admin-section legal-copy">
<h2>Verantwortlicher</h2>
<p>Kai Piekny, Fleyerstr. 33, 58097 Hagen<br><a href="mailto:konzert@pinguholic.de">konzert@pinguholic.de</a></p>
<h2>Welche Daten werden gespeichert?</h2>
<p>Für die Nutzung werden insbesondere Benutzername, E-Mail-Adresse, Passwort-Hash, Anzeigename, optionale Profil- und Instagram-Angaben, Profilbild, Freundschaften, Nachrichten, Veranstaltungsteilnahmen, Kommentare, Fotos, Patches sowie von dir angelegte Veranstaltungen gespeichert.</p>
<h2>Wofür werden sie verwendet?</h2>
<p>Die Daten werden ausschließlich für Anmeldung, Kontoverwaltung, Veranstaltungsfunktionen, Freundschaften, Nachrichten, Benachrichtigungen und die von dir gewählten Sichtbarkeitseinstellungen verarbeitet.</p>
<h2>Rechtsgrundlage und Speicherdauer</h2>
<p>Die Verarbeitung erfolgt im geschlossenen Projektbetrieb zur Bereitstellung der gewünschten Funktionen und soweit erforderlich auf Grundlage deiner Einwilligung. Daten bleiben gespeichert, solange dein Konto besteht oder gesetzliche Aufbewahrungspflichten gelten. Nicht mehr benötigte Daten werden gelöscht.</p>
<h2>Weitergabe und externe Dienste</h2>
<p>Es werden keine Werbe- oder Trackingdienste eingesetzt. Bei der Veranstaltungsortsuche können Suchanfragen an einen externen Geocoding-Dienst übermittelt werden. Externe Flyer- und Instagram-Links werden beim Aufruf direkt von deinem Browser geladen; dafür gelten die Datenschutzbestimmungen des jeweiligen Anbieters.</p>
<h2>Deine Rechte</h2>
<p>Du kannst Auskunft, Berichtigung, Löschung, Einschränkung der Verarbeitung und soweit anwendbar Datenübertragbarkeit verlangen. Einen Export deiner gespeicherten Anwendungsdaten findest du klein am Ende des eigenen Profilbereichs. Anfragen bitte an <a href="mailto:konzert@pinguholic.de">konzert@pinguholic.de</a>.</p>
<h2>Cookies und Sicherheit</h2>
<p>Für die Anmeldung wird ausschließlich ein technisch notwendiges, HttpOnly-Sitzungscookie verwendet. Im späteren HTTPS-Betrieb wird es zusätzlich mit dem Secure-Flag gesetzt. Passwörter werden nicht im Klartext gespeichert.</p>
<p class="legal-note">Diese Information ist eine technische Projektgrundlage und ersetzt keine individuelle rechtliche Prüfung. Vor einer öffentlichen Veröffentlichung sollten Hostinganbieter, Auftragsverarbeiter, Löschfristen und der externe Geocoding-Dienst konkret ergänzt und geprüft werden.</p>
</section>
</main>
</body>
</html>
+3 -2
View File
@@ -3,13 +3,14 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ concert.artist }} bearbeiten · Pingu Concerts</title>
<title>{{ concert.artist }} bearbeiten · MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<header>
<div class="header-inner">
<a href="/" class="logo">🎸 Pingu <span>Concerts</span></a>
<a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a>
{% include '_user_menu.html' %}
</div>
</header>
+17
View File
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="de">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Impressum · MetalCircle</title><link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png"><link rel="stylesheet" href="/static/css/style.css"></head>
<body>
<header><div class="header-inner"><a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a></div></header>
<main>
<div class="page-title"><h1>Impressum</h1><p>Anbieterkennzeichnung</p></div>
<section class="admin-section legal-copy">
<h2>MetalCircle</h2>
<p><strong>Verantwortlich für den Inhalt</strong></p>
<p>Kai Piekny<br>Fleyerstr. 33<br>58097 Hagen<br>Deutschland</p>
<p>E-Mail: <a href="mailto:konzert@pinguholic.de">konzert@pinguholic.de</a></p>
<p class="legal-note">Dieses private Projekt befindet sich derzeit im geschlossenen Betrieb. Vor einer Veröffentlichung werden die Angaben und rechtlichen Anforderungen nochmals geprüft.</p>
</section>
</main>
</body>
</html>
+5 -4
View File
@@ -10,7 +10,8 @@
content="width=device-width, initial-scale=1.0"
>
<title>Pingu Concerts</title>
<title>MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link
rel="stylesheet"
@@ -175,7 +176,7 @@
}
.page-header { padding: 24px; border: 1px solid #5f1515; border-left: 4px solid #dc2626; border-radius: 14px; background: linear-gradient(110deg, rgba(10,10,10,.9), rgba(69,10,10,.28)); box-shadow: 0 12px 30px rgba(0,0,0,.3); }
.page-header h1 { font-family: "Metal Mania", Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif; letter-spacing: .05em; text-transform: uppercase; text-shadow: 0 2px 18px rgba(185, 28, 28, .45); }
.page-header h1 { font-family: "Nimbus Sans Narrow", Impact, Haettenschweiler, "Arial Narrow Bold", sans-serif; letter-spacing: .05em; text-transform: uppercase; text-shadow: 0 2px 18px rgba(185, 28, 28, .45); }
.new-concert-button { background: #991b1b; border: 1px solid #dc2626; }
.new-concert-button:hover { background: #b91c1c; }
.admin-button:hover { border-color: #dc2626; }
@@ -232,11 +233,11 @@
<div>
<h1>
{% if archive %}☠ Vergangene Veranstaltungen{% else %}🐧 Pingu Concerts{% endif %}
{% if archive %}☠ Vergangene Veranstaltungen{% else %}<img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle">{% endif %}
</h1>
<div class="subtitle">
{% if archive %}Das Archiv vergangener Nächte{% else %}Konzerte, Festivals und alles davor{% endif %}
<strong>Enter the Pit. Join the Circle.</strong>
</div>
</div>
+3 -3
View File
@@ -3,13 +3,14 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Anmelden · Pingu Concerts</title>
<title>Anmelden · MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body>
<header>
<div class="header-inner">
<a href="/" class="logo">🎸 Pingu <span>Concerts</span></a>
<a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a>
</div>
</header>
<main>
@@ -33,7 +34,6 @@
</p>
<button type="submit" class="button">Anmelden</button>
<p><small>Passwort vergessen? Bitte einen Admin um einen zeitlich begrenzten Reset-Link.</small></p>
<a href="/" class="button button-secondary">Abbrechen</a>
</form>
</section>
</main>
+35 -2
View File
@@ -3,7 +3,8 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nachrichten · Pingu Concerts</title>
<title>Nachrichten · MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link rel="stylesheet" href="/static/css/style.css">
<style>
.conversation-list { display: grid; gap: 10px; }
@@ -23,11 +24,23 @@
.chat-form { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; margin-top: 12px; max-width: none; }
.chat-form textarea { min-height: 76px; margin: 0; resize: vertical; }
.empty-chat { color: var(--muted); text-align: center; margin: auto; }
.message-notifications { margin-bottom: 24px; padding: 16px; background: rgba(69,10,10,.45); border: 1px solid #7f1d1d; border-radius: 14px; }
.message-notifications h2, .conversation-heading { margin: 0 0 12px; font-size: 1.15rem; }
.notification-row { display: flex; align-items: center; gap: 11px; padding: 11px; color: var(--text); border-top: 1px solid rgba(127,29,29,.55); }
a.notification-row:hover { background: rgba(127,29,29,.25); }
.notification-icon { flex: 0 0 auto; font-size: 1.35rem; }
.notification-row > span:nth-child(2) { min-width: 0; flex: 1; }
.notification-row small { display: block; margin-top: 3px; color: var(--muted); }
.notification-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.notification-actions form { margin: 0; }
.notification-actions .button { padding: 7px 10px; font-size: .82rem; }
.notification-link { color: #fca5a5; white-space: nowrap; }
.conversation-heading { margin-top: 20px; }
@media (max-width: 600px) { .chat-form { grid-template-columns: 1fr; } .chat-bubble { max-width: 90%; } }
</style>
</head>
<body>
<header><div class="header-inner"><a href="/" class="logo">🎸 Pingu <span>Concerts</span></a>{% include '_user_menu.html' %}</div></header>
<header><div class="header-inner"><a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a>{% include '_user_menu.html' %}</div></header>
<main>
{% if partner %}
<div class="chat-header">
@@ -45,6 +58,26 @@
<p><a class="button button-secondary" href="/messages">← Alle Nachrichten</a></p>
{% else %}
<div class="page-title"><h1>🤘 Nachrichten</h1><p>Private Chats mit deinen Freunden.</p></div>
{% if friend_requests or event_invitations %}
<section class="message-notifications">
<h2>Neue Anfragen</h2>
{% for request in friend_requests %}
<div class="notification-row">
<span class="notification-icon">🤝</span>
<span><strong>{{ request.display_name }}</strong> möchte sich mit dir befreunden.<small>{{ request.created_at }}</small></span>
<span class="notification-actions"><form method="post" action="/friendships/{{ request.id }}/accept"><input type="hidden" name="return_to" value="/messages"><button class="button" type="submit">Annehmen</button></form><form method="post" action="/friendships/{{ request.id }}/decline"><input type="hidden" name="return_to" value="/messages"><button class="button button-secondary" type="submit">Ablehnen</button></form></span>
</div>
{% endfor %}
{% for invitation in event_invitations %}
<a class="notification-row" href="/concerts/{{ invitation.concert_id }}">
<span class="notification-icon">✉️</span>
<span><strong>{{ invitation.artist }}</strong> Einladung von {{ invitation.invited_by }}<small>{{ invitation.date }}</small></span>
<span class="notification-link">Ansehen →</span>
</a>
{% endfor %}
</section>
{% endif %}
<h2 class="conversation-heading">Unterhaltungen</h2>
<div class="conversation-list">
{% for conversation in conversations %}
<a class="conversation-card" href="/messages/{{ conversation.username }}">
+4 -3
View File
@@ -10,7 +10,8 @@
content="width=device-width, initial-scale=1.0"
>
<title>Veranstaltung hinzufügen · Pingu Concerts</title>
<title>Veranstaltung hinzufügen · MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link
rel="stylesheet"
@@ -75,7 +76,7 @@
<div class="header-inner">
<a href="/" class="logo">
🎸 Pingu <span>Concerts</span>
<img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle">
</a>
{% include '_user_menu.html' %}
@@ -322,7 +323,7 @@
<label for="flyer-url">🔗 Flyer extern verlinken <small>(bevorzugt)</small></label>
<input type="url" id="flyer-url" name="flyer_url" placeholder="https://veranstalter.example/flyer.jpg">
<div class="flyer-help">Bitte möglichst den offiziellen Flyer des Veranstalters oder der Band verlinken. Das Bild wird nicht auf Pingu Concerts kopiert; der Link wird als Quelle ausgewiesen.</div>
<div class="flyer-help">Bitte möglichst den offiziellen Flyer des Veranstalters oder der Band verlinken. Das Bild wird nicht auf MetalCircle kopiert; der Link wird als Quelle ausgewiesen.</div>
<label for="flyer">
+2 -2
View File
@@ -1,4 +1,4 @@
<!DOCTYPE html><html lang="de"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Passwort zurücksetzen · Pingu Concerts</title><link rel="stylesheet" href="/static/css/style.css"></head><body>
<header><div class="header-inner"><a href="/" class="logo">🎸 Pingu <span>Concerts</span></a></div></header><main><div class="page-title"><h1>Passwort zurücksetzen</h1></div><section class="empty">
<!DOCTYPE html><html lang="de"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Passwort zurücksetzen · MetalCircle</title><link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png"><link rel="stylesheet" href="/static/css/style.css"></head><body>
<header><div class="header-inner"><a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a></div></header><main><div class="page-title"><h1>Passwort zurücksetzen</h1></div><section class="empty">
{% if error %}<p role="alert">{{ error }}</p>{% endif %}<form method="post" action="/password-reset/{{ token }}"><label>Neues Passwort<br><input type="password" name="password" minlength="10" required autocomplete="new-password"></label><br><label>Passwort wiederholen<br><input type="password" name="password_repeat" minlength="10" required autocomplete="new-password"></label><br><button class="button" type="submit">Passwort speichern</button></form>
</section></main></body></html>
+4 -2
View File
@@ -3,7 +3,8 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ profile.display_name }} · Pingu Concerts</title>
<title>{{ profile.display_name }} · MetalCircle</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<link rel="stylesheet" href="/static/css/style.css">
<style>
.profile-layout { display: grid; grid-template-columns: minmax(240px, .8fr) minmax(0, 1.4fr); gap: 24px; align-items: start; }
@@ -57,7 +58,7 @@
<body>
<header>
<div class="header-inner">
<a href="/" class="logo">🎸 Pingu <span>Concerts</span></a>
<a href="/" class="logo"><img class="brand-logo" src="/static/images/metalcircle-full.png" alt="MetalCircle"></a>
{% include '_user_menu.html' %}
</div>
</header>
@@ -186,6 +187,7 @@
<span class="avatar-upload-status" id="avatar-upload-status">Große Bilder werden vor dem Upload automatisch optimiert.</span>
<button class="button" type="submit">Profil speichern</button>
</form>
<p class="data-export"><a href="/profile/export">Meine gespeicherten Daten exportieren (JSON)</a></p>
</section>
{% endif %}
</main>
+4 -3
View File
@@ -4,7 +4,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pingu Concerts - Registrierung</title>
<title>MetalCircle - Registrierung</title>
<link rel="icon" type="image/png" href="/static/images/metalcircle-circle.png">
<style>
body {
@@ -31,12 +32,12 @@
<body>
<h1>🎸 Pingu Concerts</h1>
<p><img src="/static/images/metalcircle-full.png" alt="MetalCircle" style="display:block;max-width:100%;height:auto;margin:0 auto 24px"></p>
<h2>Einladung angenommen</h2>
<p>
Erstelle deinen Account für Pingu Concerts.
Erstelle deinen Account für MetalCircle.
</p>
<form method="post" action="/register">