feat: Sleek Frontend-Redesign — Anthrazit, Off-White, Avatar-Initialen, entfärbte Badges, Mobile-First
Quality Gate / 🛡️ Lint + Type Check + Tests (push) Failing after 11m0s

This commit is contained in:
Hermes Agent
2026-06-25 09:34:39 +02:00
parent 3309062f26
commit a94dbe2659
+211 -206
View File
@@ -2758,8 +2758,8 @@ def public_frontend():
filter_html += f'<input type="hidden" name="cat" value="{cat_filter}">' filter_html += f'<input type="hidden" name="cat" value="{cat_filter}">'
filter_html += '<select name="sort" onchange="this.form.submit()" class="hall-select">' filter_html += '<select name="sort" onchange="this.form.submit()" class="hall-select">'
filter_html += f'<option value="neu" {"selected" if sort == "neu" else ""}>Neueste zuerst</option>' filter_html += f'<option value="neu" {"selected" if sort == "neu" else ""}>Neueste zuerst</option>'
filter_html += f'<option value="beliebt" {"selected" if sort == "beliebt" else ""}><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#20228a" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:3px;"><path d="M7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/><path d="M7 11h11.5a2.5 2.5 0 0 1 2.5 2.5v.5a2.5 2.5 0 0 1-2.5 2.5h-2.5"/><path d="M16 16.5V19a3 3 0 0 1-6 1.5L7 11"/></svg> Beliebteste</option>' filter_html += f'<option value="beliebt" {"selected" if sort == "beliebt" else ""}><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:3px;"><path d="M7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/><path d="M7 11h11.5a2.5 2.5 0 0 1 2.5 2.5v.5a2.5 2.5 0 0 1-2.5 2.5h-2.5"/><path d="M16 16.5V19a3 3 0 0 1-6 1.5L7 11"/></svg> Beliebteste</option>'
filter_html += f'<option value="gesehen" {"selected" if sort == "gesehen" else ""}><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#20228a" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:3px;"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg> Meist gesehen</option>' filter_html += f'<option value="gesehen" {"selected" if sort == "gesehen" else ""}><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:3px;"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg> Meist gesehen</option>'
filter_html += '</select></form> ' filter_html += '</select></form> '
if halle_filter or cat_filter or sort != "neu": if halle_filter or cat_filter or sort != "neu":
@@ -2843,6 +2843,10 @@ def public_frontend():
if not name or name.lower() in ("unknown", "anonym"): if not name or name.lower() in ("unknown", "anonym"):
name = "Anonym" name = "Anonym"
# Avatar: Initialen im Kreis
initials = "".join(w[0].upper() for w in name.split() if w)[:2] or "?"
avatar_html = f'<span class="author-avatar">{initials}</span>'
summary_text = (r["display_text"] or r["summary"] or r["content"] or "") summary_text = (r["display_text"] or r["summary"] or r["content"] or "")
# Kurzer Teaser: ersten Satz oder max 80 Zeichen # Kurzer Teaser: ersten Satz oder max 80 Zeichen
first_sentence = summary_text.split(".")[0].strip() first_sentence = summary_text.split(".")[0].strip()
@@ -2852,7 +2856,7 @@ def public_frontend():
first_sentence += "." first_sentence += "."
preview = first_sentence preview = first_sentence
date_str = (r["published_at"] or r["created_at"] or "") date_str = (r["published_at"] or r["created_at"] or "")
# Format with relative + absolute time # Zeitformat: dezent, dimmed gray
time_html = "" time_html = ""
try: try:
from datetime import datetime from datetime import datetime
@@ -2861,66 +2865,58 @@ def public_frontend():
diff = now - dt diff = now - dt
if diff.days == 0: if diff.days == 0:
if diff.seconds < 3600: if diff.seconds < 3600:
time_html = f'<span class="story-time-rel">vor {diff.seconds // 60} Min.</span>' time_html = f'vor {diff.seconds // 60} Min.'
else: else:
time_html = f'<span class="story-time-rel">heute</span> {dt.strftime("%H:%M")} Uhr' time_html = f'heute {dt.strftime("%H:%M")}'
elif diff.days == 1: elif diff.days == 1:
time_html = f'<span class="story-time-rel">gestern</span> {dt.strftime("%H:%M")} Uhr' time_html = f'gestern {dt.strftime("%H:%M")}'
elif diff.days < 7: elif diff.days < 7:
time_html = f'<span class="story-time-rel">vor {diff.days} Tagen</span> {dt.strftime("%H:%M")}' time_html = f'vor {diff.days} Tagen'
else: else:
time_html = dt.strftime("%d.%m.%y %H:%M") + " Uhr" time_html = dt.strftime("%d.%m.%y %H:%M")
date_str = dt.strftime("%d. %B %Y")
except: except:
pass pass
text_only_class = " text-only" if not media_first else "" # Metadata-Leiste: Avatar + Autor · Views · Comments · Like
is_ausverkauft = r["category"] == "ausverkauft" and r["spiel_titel"] meta_html = f"""<div class="card-meta">
time_block = "" <div class="meta-author">{avatar_html} {name}</div>
if time_html and not is_ausverkauft: <div class="meta-spacer"></div>
time_overlay = f'<div class="story-time-overlay">{time_html}</div>' <span class="card-meta-item"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" stroke-width="1.5" stroke-linecap="round"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>{r['views'] or 0}</span>
time_block = time_overlay # Always overlay now <span class="card-meta-item"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" stroke-width="1.5" stroke-linecap="round"><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>{r['comment_count'] or 0}</span>
elif not media_first and not is_ausverkauft: <button class="stat-like-btn" data-id="{r['id']}" data-likes="{r['likes'] or 0}"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#D1D5DB" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg> {r['likes'] or 0}</button>
time_block = '' </div>"""
is_ausverkauft = r["category"] == "ausverkauft" and r["spiel_titel"]
# Zeit-Block oben (für Text-only Karten)
time_top = f'<div class="story-time">{time_html}</div>' if time_html else ''
# Badge-Titel vorbereiten (vermeidet Escaping-Probleme)
badge_title = f'<span class="badge-title"> · {r["spiel_titel"]}</span>' if r["spiel_titel"] else ""
if not media_first: if not media_first:
# Text-only card: link-wrapped, time overlay at top (same as media cards) # Text-only card
cards += f"""<a href="/beitrag/{r['id']}" class="card-link"> cards += f"""<a href="/beitrag/{r['id']}" class="card-link">
<article class="story-card text-only"> <article class="story-card text-only">
""" + time_block + """ {time_top}
""" + (f'<div class="story-halle-badge"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5" stroke-linecap="round" style="vertical-align:middle;margin-right:2px;"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg> {r["halle"]}</div>' if r["halle"] else '') + """ {f'<div class="story-halle-badge"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" stroke-width="2" stroke-linecap="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg> {r["halle"]}</div>' if r["halle"] else ''}
""" + (f'<div class="story-ausverkauft-badge"><span class="badge-icon">🚫</span> AUSVERKAUFT{("<span class=\"badge-title\"> · " + r["spiel_titel"] + "</span>") if r["spiel_titel"] else ""}</div>' if r["category"] == "ausverkauft" else '') + """ {f'<div class="story-ausverkauft-badge"><span class="badge-icon">🚫</span> AUSVERKAUFT{badge_title}</div>' if r["category"] == "ausverkauft" else ''}
<div class="card-content"> <div class="card-content">
<p class="story-preview">""" + preview + """</p> <p class="story-preview">{preview}</p>
<div class="card-stats"> {meta_html}
<span class="stat-views"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:2px;"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>""" + str(r['views'] or 0) + """</span>
<span class="stat-comments"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:2px;"><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>""" + str(r['comment_count'] or 0) + """</span>
<button class="stat-like-btn" data-id=""" + str(r['id']) + """ data-likes=""" + str(r['likes'] or 0) + """><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#20228a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:2px;"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg> """ + str(r['likes'] or 0) + """</button>
</div>
<div class="story-meta">
<span class="story-type">""" + type_emoji + """</span>
<span class="story-author"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#20228a" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:3px;"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>""" + name + """</span>
</div>
</div> </div>
</article> </article>
</a>""" </a>"""
else: else:
# Media card: author at bottom (same as text-only) # Media card
cards += f"""<article class="story-card"> cards += f"""<article class="story-card">
""" + media_first + time_block + """ {media_first}
""" + (f'<div class="story-halle-badge"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.5" stroke-linecap="round" style="vertical-align:middle;margin-right:2px;"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg> {r["halle"]}</div>' if r["halle"] else '') + """ {f'<div class="story-time-overlay">{time_html}</div>' if time_html else ''}
""" + (f'<div class="story-ausverkauft-badge"><span class="badge-icon">🚫</span> AUSVERKAUFT{("<span class=\"badge-title\"> · " + r["spiel_titel"] + "</span>") if r["spiel_titel"] else ""}</div>' if r["category"] == "ausverkauft" else '') + """ {f'<div class="story-halle-badge"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#9CA3AF" stroke-width="2" stroke-linecap="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg> {r["halle"]}</div>' if r["halle"] else ''}
{f'<div class="story-ausverkauft-badge"><span class="badge-icon">🚫</span> AUSVERKAUFT{badge_title}</div>' if r["category"] == "ausverkauft" else ''}
<div class="card-content"> <div class="card-content">
<p class="story-preview">""" + preview + """</p> <p class="story-preview">{preview}</p>
<div class="card-stats"> {meta_html}
<span class="stat-views"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:2px;"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>""" + str(r['views'] or 0) + """</span>
<span class="stat-comments"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#999" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:2px;"><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>""" + str(r['comment_count'] or 0) + """</span>
<button class="stat-like-btn" data-id=""" + str(r['id']) + """ data-likes=""" + str(r['likes'] or 0) + """><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#20228a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="vertical-align:middle;margin-right:2px;"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg> """ + str(r['likes'] or 0) + """</button>
</div>
<div class="story-meta">
<span class="story-type">""" + type_emoji + """</span>
<span class="story-author"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#20228a" stroke-width="2" stroke-linecap="round" style="vertical-align:middle;margin-right:3px;"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>""" + name + """</span>
</div>
</div> </div>
</article>""" </article>"""
@@ -2934,271 +2930,280 @@ def public_frontend():
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600;14..32,700;14..32,800&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,400;14..32,500;14..32,600;14..32,700;14..32,800&display=swap" rel="stylesheet">
<style> <style>
* { margin:0; padding:0; box-sizing:border-box; } * { margin:0; padding:0; box-sizing:border-box; }
body { font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; background:#E8E4DC; color:#1a1a2e; min-height:100vh; } body { font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; background:#F9FAFB; color:#1F2937; min-height:100vh; -webkit-font-smoothing:antialiased; }
/* Header dark bar like SPIEL Essen */ /* Header clean anthracite */
.site-header { background:#20228a; padding:0.75rem 1.2rem; display:flex; align-items:center; flex-wrap:wrap; gap:0.5rem; position:sticky; top:0; z-index:100; box-shadow:0 2px 12px rgba(0,0,0,0.15); } .site-header { background:#1F2937; padding:0.75rem 1.2rem; display:flex; align-items:center; flex-wrap:wrap; gap:0.5rem; position:sticky; top:0; z-index:100; box-shadow:0 1px 3px rgba(0,0,0,0.08); }
.site-logo { display:flex; align-items:center; gap:0.5rem; text-decoration:none; color:#fff; min-width:0; flex-shrink:1; } .site-logo { display:flex; align-items:center; gap:0.5rem; text-decoration:none; color:#F9FAFB; min-width:0; flex-shrink:1; }
.site-logo .logo-icon { width:36px; height:36px; background:#20228a; border-radius:8px; display:flex; align-items:center; justify-content:center; font-size:1.3rem; flex-shrink:0; } .site-logo .logo-icon { width:36px; height:36px; background:#374151; border-radius:8px; display:flex; align-items:center; justify-content:center; font-size:1.3rem; flex-shrink:0; }
.site-logo .logo-text { font-weight:800; font-size:1.05rem; letter-spacing:-0.01em; color:#fff; white-space:nowrap; } .site-logo .logo-text { font-weight:800; font-size:1.05rem; letter-spacing:-0.01em; color:#F9FAFB; white-space:nowrap; }
.site-logo .logo-sub { font-weight:400; color:#888; font-size:0.75rem; } .site-logo .logo-sub { font-weight:400; color:#9CA3AF; font-size:0.75rem; }
.site-logo-sub { font-size:0.68rem; font-weight:500; color:rgba(255,255,255,0.7); letter-spacing:0.03em; margin-left:0.3rem; white-space:normal; word-break:break-word; } .site-logo-sub { font-size:0.68rem; font-weight:500; color:#9CA3AF; letter-spacing:0.03em; margin-left:0.3rem; white-space:normal; word-break:break-word; }
.site-header .header-right { margin-left:auto; } .site-header .header-right { margin-left:auto; }
.site-header .header-right a { color:#aaa; text-decoration:none; font-size:0.8rem; transition:color 0.2s; } .site-header .header-right a { color:#9CA3AF; text-decoration:none; font-size:0.8rem; transition:color 0.2s; }
.site-header .header-right a:hover { color:#fff; } .site-header .header-right a:hover { color:#F9FAFB; }
.filter-toggle-btn { background:rgba(255,255,255,0.12); border:1.5px solid rgba(255,255,255,0.25); border-radius:8px; color:#fff; font-size:0.78rem; font-weight:600; cursor:pointer; padding:0.35rem 0.7rem; line-height:1.3; transition:all 0.15s; margin-left:0.5rem; font-family:inherit; } .filter-toggle-btn { background:rgba(255,255,255,0.08); border:1px solid rgba(255,255,255,0.12); border-radius:8px; color:#D1D5DB; font-size:0.78rem; font-weight:600; cursor:pointer; padding:0.35rem 0.7rem; line-height:1.3; transition:all 0.15s; margin-left:0.5rem; font-family:inherit; }
.filter-toggle-btn:hover { background:rgba(255,255,255,0.22); border-color:rgba(255,255,255,0.5); } .filter-toggle-btn:hover { background:rgba(255,255,255,0.15); border-color:rgba(255,255,255,0.25); }
.filter-toggle-btn.active { background:rgba(255,255,255,0.25); border-color:#fff; } .filter-toggle-btn.active { background:rgba(255,255,255,0.2); border-color:#D1D5DB; }
.filter-collapsed { display:none; } .filter-collapsed { display:none; }
.filter-backdrop { position:fixed; inset:0; z-index:100000; background:rgba(0,0,0,0.3); backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px); display:none; } .filter-backdrop { position:fixed; inset:0; z-index:100000; background:rgba(0,0,0,0.2); backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px); display:none; }
.filter-backdrop.open { display:flex; align-items:flex-start; justify-content:center; padding-top:4rem; } .filter-backdrop.open { display:flex; align-items:flex-start; justify-content:center; padding-top:4rem; }
.filter-overlay { background:#fff; border-radius:16px; box-shadow:0 12px 48px rgba(0,0,0,0.22); padding:1.2rem 1.5rem; width:90vw; max-width:600px; animation:fadeDown 0.2s ease; } .filter-overlay { background:#fff; border-radius:16px; box-shadow:0 12px 48px rgba(0,0,0,0.12); padding:1.2rem 1.5rem; width:90vw; max-width:600px; animation:fadeDown 0.2s ease; }
/* Offcanvas navigation */ /* Offcanvas navigation */
.nav-toggle { background:none; border:none; color:#fff; font-size:1.3rem; cursor:pointer; padding:0.3rem 0.4rem; line-height:1; margin-right:0.5rem; transition:opacity 0.2s; } .nav-toggle { background:none; border:none; color:#D1D5DB; font-size:1.3rem; cursor:pointer; padding:0.3rem 0.4rem; line-height:1; margin-right:0.5rem; transition:opacity 0.2s; }
.nav-toggle:hover { opacity:0.7; } .nav-toggle:hover { opacity:0.7; }
.offcanvas-backdrop { position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:200; opacity:0; pointer-events:none; transition:opacity 0.3s ease; } .offcanvas-backdrop { position:fixed; inset:0; background:rgba(0,0,0,0.3); z-index:200; opacity:0; pointer-events:none; transition:opacity 0.3s ease; }
.offcanvas-backdrop.open { opacity:1; pointer-events:auto; } .offcanvas-backdrop.open { opacity:1; pointer-events:auto; }
.offcanvas-nav { position:fixed; top:0; left:0; width:280px; height:100%; height:100dvh; background:#fff; z-index:201; transform:translateX(-100%); transition:transform 0.3s cubic-bezier(0.4,0,0.2,1); box-shadow:4px 0 24px rgba(0,0,0,0.15); display:flex; flex-direction:column; } .offcanvas-nav { position:fixed; top:0; left:0; width:280px; height:100%; height:100dvh; background:#fff; z-index:201; transform:translateX(-100%); transition:transform 0.3s cubic-bezier(0.4,0,0.2,1); box-shadow:4px 0 24px rgba(0,0,0,0.1); display:flex; flex-direction:column; }
.offcanvas-nav.open { transform:translateX(0); } .offcanvas-nav.open { transform:translateX(0); }
.offcanvas-nav-header { background:#20228a; color:#fff; padding:1.2rem 1.5rem; display:flex; align-items:center; justify-content:space-between; } .offcanvas-nav-header { background:#1F2937; color:#F9FAFB; padding:1.2rem 1.5rem; display:flex; align-items:center; justify-content:space-between; }
.offcanvas-nav-header .nav-logo { font-weight:800; font-size:1rem; } .offcanvas-nav-header .nav-logo { font-weight:800; font-size:1rem; }
.offcanvas-nav-header .nav-close { background:none; border:none; color:#fff; font-size:1.4rem; cursor:pointer; line-height:1; } .offcanvas-nav-header .nav-close { background:none; border:none; color:#D1D5DB; font-size:1.4rem; cursor:pointer; line-height:1; }
.offcanvas-nav-links { list-style:none; padding:1rem 0; flex:1; } .offcanvas-nav-links { list-style:none; padding:1rem 0; flex:1; }
.offcanvas-nav-links li { } .offcanvas-nav-links li { }
.offcanvas-nav-links a { display:block; padding:0.75rem 1.5rem; color:#1a1a2e; text-decoration:none; font-size:0.95rem; font-weight:500; transition:background 0.15s; } .offcanvas-nav-links a { display:block; padding:0.75rem 1.5rem; color:#1F2937; text-decoration:none; font-size:0.95rem; font-weight:500; transition:background 0.15s; }
.offcanvas-nav-links a:hover { background:#f0ede6; } .offcanvas-nav-links a:hover { background:#F3F4F6; }
.offcanvas-nav-links .nav-section { padding:0.5rem 1.5rem 0.2rem; font-size:0.7rem; font-weight:700; text-transform:uppercase; letter-spacing:0.05em; color:#888; } .offcanvas-nav-links .nav-section { padding:0.5rem 1.5rem 0.2rem; font-size:0.7rem; font-weight:700; text-transform:uppercase; letter-spacing:0.05em; color:#9CA3AF; }
.offcanvas-nav-footer { padding:1rem 1.5rem; border-top:1px solid #e0ddd6; font-size:0.75rem; color:#888; } .offcanvas-nav-footer { padding:1rem 1.5rem; border-top:1px solid #E5E7EB; font-size:0.75rem; color:#9CA3AF; }
/* Main grid masonry (CSS columns) */ /* Main grid single column (mobile-first) */
.main-grid { max-width:1300px; margin:1.5rem auto; padding:0 1rem; column-count:4; column-gap:1.2rem; } .main-grid { max-width:640px; margin:1rem auto; padding:0 0.8rem; display:flex; flex-direction:column; gap:1rem; }
/* Card link wrapper (text-only) */ /* Card clean, more whitespace */
.card-link { text-decoration:none; color:inherit; display:inline-block; width:100%; margin-bottom:1.2rem; break-inside:avoid; } .story-card { background:#fff; border-radius:16px; overflow:hidden; box-shadow:0 1px 3px rgba(0,0,0,0.04),0 1px 2px rgba(0,0,0,0.03); transition:box-shadow 0.2s ease; position:relative; }
.card-link:hover .story-card { transform:scale(1.03); box-shadow:0 18px 50px rgba(0,0,0,0.35),0 5px 20px rgba(0,0,0,0.18); } .story-card:hover { box-shadow:0 4px 16px rgba(0,0,0,0.06); }
/* Card masonry tiles, compact */
.story-card { background:#fff; border-radius:14px; overflow:hidden; box-shadow:0 4px 18px rgba(0,0,0,0.10),0 1px 4px rgba(0,0,0,0.05); transition:box-shadow 0.35s ease,transform 0.35s ease,filter 0.35s ease; display:inline-block; width:100%; margin-bottom:1.2rem; break-inside:avoid; }
.story-card:hover { transform:scale(1.03); box-shadow:0 18px 50px rgba(0,0,0,0.35),0 5px 20px rgba(0,0,0,0.18); }
/* Blur the rest when hovering a card (desktop only) */
@media(min-width:901px) {
.main-grid:has(.story-card:hover) .story-card:not(:hover) { filter:blur(1px); }
body:has(.story-card:hover) .site-header,
body:has(.story-card:hover) .site-footer { filter:blur(1px); transition:filter 0.35s ease; }
}
a.card-link .story-card { margin-bottom:0; }
.story-card img { width:100%; height:100%; object-fit:cover; display:block; } .story-card img { width:100%; height:100%; object-fit:cover; display:block; }
.story-card video { width:100%; height:auto; max-height:600px; object-fit:contain; display:block; background:#000; } .story-card video { width:100%; height:auto; max-height:600px; object-fit:contain; display:block; background:#000; }
.story-card { position:relative; } .story-card audio { width:100%; margin-top:0.5rem; }
.story-halle-badge { position:absolute; top:0; right:0; background:#20228a; color:#fff; padding:0.25rem 0.65rem; border-radius:0 0 0 5px; font-size:0.78rem; font-weight:700; letter-spacing:0.03em; z-index:5; box-shadow:0 2px 6px rgba(0,0,0,0.3); }
.story-ausverkauft-badge { position:absolute; top:0; left:0; right:0; z-index:7; background:linear-gradient(180deg,#dc3545 0%,#b02a37 100%); color:#fff; padding:0.5rem 1rem; font-size:0.8rem; font-weight:800; letter-spacing:0.12em; text-align:center; box-shadow:0 2px 12px rgba(220,53,69,0.5); display:flex; align-items:center; justify-content:center; gap:0.5rem; flex-wrap:wrap; } /* Hall badge subtle gray outline */
.story-ausverkauft-badge .badge-icon { font-size:0.95rem; } .story-halle-badge { position:absolute; top:0.5rem; right:0.5rem; background:rgba(255,255,255,0.92); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px); color:#6B7280; padding:0.2rem 0.55rem; border-radius:6px; font-size:0.72rem; font-weight:600; letter-spacing:0.02em; z-index:5; border:1px solid rgba(0,0,0,0.06); }
.story-ausverkauft-badge .badge-title { font-weight:500; letter-spacing:0.02em; font-size:0.72rem; opacity:0.9; } .story-halle-badge svg { stroke:#9CA3AF !important; }
.card-content { padding:0.45rem 0.85rem 0.55rem; display:flex; flex-direction:column; gap:0.2rem; }
.story-meta { display:flex; align-items:center; gap:0.4rem; flex-wrap:wrap; padding-top:0.3rem; margin-top:0.25rem; border-top:1px solid #f0ede6; } /* Ausverkauft badge keep red but cleaner */
.story-type { font-size:0.8rem; } .story-ausverkauft-badge { position:absolute; top:0; left:0; right:0; z-index:7; background:linear-gradient(180deg,#EF4444 0%,#DC2626 100%); color:#fff; padding:0.4rem 1rem; font-size:0.75rem; font-weight:700; letter-spacing:0.08em; text-align:center; box-shadow:0 2px 8px rgba(220,38,38,0.3); display:flex; align-items:center; justify-content:center; gap:0.4rem; flex-wrap:wrap; }
.story-author { font-weight:600; color:#20228a; font-size:0.78rem; } .story-ausverkauft-badge .badge-icon { font-size:0.9rem; }
.story-date { color:#999; font-size:0.7rem; margin-left:auto; } .story-ausverkauft-badge .badge-title { font-weight:500; letter-spacing:0.01em; font-size:0.7rem; opacity:0.85; }
.story-time { font-size:0.7rem; color:#666; font-weight:500; }
.story-time-rel { color:#dc3545; font-weight:700; } /* Card content more whitespace */
.story-time-overlay { position:absolute; top:0; left:0; right:0; z-index:4; background:rgba(255,255,255,0.55); backdrop-filter:blur(10px); -webkit-backdrop-filter:blur(10px); padding:0.3rem 0.65rem; font-size:0.8rem; font-weight:700; letter-spacing:0.02em; line-height:1.3; } .card-content { padding:0.75rem 1rem 0.7rem; display:flex; flex-direction:column; gap:0.35rem; }
.story-time-overlay .story-time-rel { color:#dc3545; }
/* Time at top, small, dimmed */
.story-time { font-size:0.7rem; color:#9CA3AF; font-weight:400; letter-spacing:0.01em; }
.story-time-rel { color:#9CA3AF; font-weight:400; }
/* Time overlay (on media cards) subtle */
.story-time-overlay { position:absolute; top:0; left:0; padding:0.35rem 0.6rem; z-index:4; font-size:0.72rem; color:#6B7280; font-weight:500; letter-spacing:0.01em; }
/* Preview text */
.story-preview { display:none; } .story-preview { display:none; }
.text-only .story-preview { display:-webkit-box; -webkit-line-clamp:4; -webkit-box-orient:vertical; overflow:hidden; text-overflow:ellipsis; font-size:0.8rem; line-height:1.4; color:#444; margin-bottom:0.35rem; } .text-only .story-preview { display:-webkit-box; -webkit-line-clamp:4; -webkit-box-orient:vertical; overflow:hidden; text-overflow:ellipsis; font-size:0.85rem; line-height:1.55; color:#4B5563; margin-bottom:0; }
.text-only .card-content { position:relative; padding:2rem 0.85rem 0.5rem; } .text-only .card-content { padding:0.8rem 1rem 0.7rem; }
/* Card stats (views + likes) */ /* Text-only card border */
.card-stats { display:flex; align-items:center; gap:0.6rem; padding-top:0.35rem; margin-top:0.3rem; border-top:1px solid #f0ede6; } .text-only { border:1px solid #F3F4F6; }
.stat-views { font-size:0.68rem; color:#999; display:flex; align-items:center; gap:0.2rem; }
.stat-like-btn { background:none; border:1.5px solid #e0dcd3; border-radius:999px; padding:0.2rem 0.55rem; font-size:0.7rem; cursor:pointer; color:#888; font-family:inherit; transition:all 0.15s; display:flex; align-items:center; gap:0.15rem; -webkit-tap-highlight-color:transparent; } /* Card link */
.stat-like-btn:hover { border-color:#20228a; color:#20228a; background:rgba(32,34,138,0.05); } .card-link { text-decoration:none; color:inherit; display:block; }
.stat-like-btn.liked { background:#20228a; color:#fff; border-color:#20228a; font-weight:600; }
/* Author avatar */
.author-avatar { width:24px; height:24px; border-radius:50%; background:#E5E7EB; color:#6B7280; display:inline-flex; align-items:center; justify-content:center; font-size:0.65rem; font-weight:700; letter-spacing:0.02em; flex-shrink:0; }
/* Metadata row ONE clean line at bottom */
.card-meta { display:flex; align-items:center; gap:0.5rem; padding-top:0.5rem; margin-top:0.35rem; border-top:1px solid #F3F4F6; flex-wrap:wrap; }
.card-meta-item { display:flex; align-items:center; gap:0.2rem; font-size:0.72rem; color:#9CA3AF; }
.card-meta-item svg { stroke:#9CA3AF; }
.meta-author { display:flex; align-items:center; gap:0.35rem; color:#6B7280; font-size:0.75rem; font-weight:500; }
.meta-spacer { flex:1; }
/* Like button subtle outline */
.stat-like-btn { background:none; border:1px solid #E5E7EB; border-radius:999px; padding:0.25rem 0.6rem; font-size:0.72rem; cursor:pointer; color:#9CA3AF; font-family:inherit; transition:all 0.15s; display:flex; align-items:center; gap:0.2rem; -webkit-tap-highlight-color:transparent; min-width:44px; min-height:36px; justify-content:center; }
.stat-like-btn svg, .stat-like-btn svg path { stroke:#D1D5DB !important; }
.stat-like-btn:hover { border-color:#9CA3AF; color:#6B7280; }
.stat-like-btn.liked { background:#EF4444; color:#fff; border-color:#EF4444; }
.stat-like-btn.liked svg, .stat-like-btn.liked svg path { stroke:#fff !important; } .stat-like-btn.liked svg, .stat-like-btn.liked svg path { stroke:#fff !important; }
.stat-like-btn:active { transform:scale(0.94); } .stat-like-btn:active { transform:scale(0.96); }
/* Frontend filter bar */ /* Filter bar */
.frontend-filter { max-width:1100px; margin:1rem auto 0; padding:0 1.5rem; display:flex; gap:0.4rem; flex-wrap:wrap; align-items:center; } .frontend-filter { max-width:640px; margin:0.5rem auto 0; padding:0 0.8rem; display:flex; gap:0.4rem; flex-wrap:wrap; align-items:center; }
.frontend-filter .filter-label { font-size:0.72rem; color:#888; font-weight:600; text-transform:uppercase; letter-spacing:0.05em; } .frontend-filter .filter-label { font-size:0.72rem; color:#9CA3AF; font-weight:600; text-transform:uppercase; letter-spacing:0.05em; }
.frontend-filter a { display:inline-block; padding:0.35rem 0.8rem; border-radius:999px; text-decoration:none; font-size:0.78rem; font-weight:500; transition:all 0.15s; border:1.5px solid transparent; } .frontend-filter a { display:inline-block; padding:0.35rem 0.8rem; border-radius:999px; text-decoration:none; font-size:0.78rem; font-weight:500; transition:all 0.15s; border:1.5px solid transparent; }
.frontend-filter a.filter-pill { background:#fff; color:#555; border-color:#ddd; } .frontend-filter a.filter-pill { background:#fff; color:#6B7280; border-color:#E5E7EB; }
.frontend-filter a.filter-pill:hover { border-color:#20228a; color:#20228a; } .frontend-filter a.filter-pill:hover { border-color:#9CA3AF; color:#374151; }
.frontend-filter a.filter-pill.active { background:#20228a; color:#fff; border-color:#20228a; font-weight:700; } .frontend-filter a.filter-pill.active { background:#1F2937; color:#fff; border-color:#1F2937; font-weight:700; }
.frontend-filter a.filter-reset { color:#999; font-size:0.75rem; } .frontend-filter a.filter-reset { color:#9CA3AF; font-size:0.75rem; }
.hall-select { appearance:none; -webkit-appearance:none; background:#fff; color:#20228a; border:1.5px solid #ddd; border-radius:999px; padding:0.35rem 2rem 0.35rem 0.9rem; font-size:0.78rem; font-weight:600; font-family:inherit; cursor:pointer; transition:all 0.15s; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2320228a' stroke-width='2.5'%3E%3Cpath d='M6 9l6 6 6-6'%3E%3C/path%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right 0.55rem center; } .hall-select { appearance:none; -webkit-appearance:none; background:#fff; color:#374151; border:1.5px solid #E5E7EB; border-radius:999px; padding:0.35rem 2rem 0.35rem 0.9rem; font-size:0.78rem; font-weight:600; font-family:inherit; cursor:pointer; transition:all 0.15s; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239CA3AF' stroke-width='2.5'%3E%3Cpath d='M6 9l6 6 6-6'%3E%3C/path%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right 0.55rem center; }
.hall-select:hover { border-color:#20228a; } .hall-select:hover { border-color:#9CA3AF; }
.hall-select:focus { outline:none; border-color:#20228a; box-shadow:0 0 0 3px rgba(32,34,138,0.12); } .hall-select:focus { outline:none; border-color:#6B7280; box-shadow:0 0 0 3px rgba(107,114,128,0.1); }
.story-card audio { width:100%; margin-top:0.8rem; }
.story-card img:not(:first-child) { height:auto; max-height:300px; object-fit:contain; margin-top:0.8rem; border-radius:8px; } /* Footer */
.story-card video:not(:first-child) { height:auto; max-height:300px; margin-top:0.8rem; border-radius:8px; } .site-footer { text-align:center; padding:2rem; border-top:1px solid #E5E7EB; margin-top:2rem; }
.site-footer p { color:#9CA3AF; font-size:0.8rem; }
.site-footer a { color:#6B7280; text-decoration:none; font-weight:600; }
.site-footer a:hover { text-decoration:underline; }
/* Video thumbnail */ /* Video thumbnail */
.video-thumb-link { display:block; text-decoration:none; } .video-thumb-link { display:block; text-decoration:none; }
.video-thumb-link:hover .play-btn { transform:scale(1.1); transition:transform 0.2s ease; background:#fff; } .video-thumb-link:hover .play-btn { transform:scale(1.1); transition:transform 0.2s ease; background:#fff; }
.video-thumb-link:hover .video-thumb img { opacity:0.85; transition:opacity 0.2s ease; } .video-thumb-link:hover .video-thumb img { opacity:0.85; transition:opacity 0.2s ease; }
/* Media preview links (image/audio) */ /* Media preview links */
.media-preview-link { display:block; text-decoration:none; } .media-preview-link { display:block; text-decoration:none; }
.media-preview-link:hover .media-crop img { opacity:0.85; transition:opacity 0.2s ease; } .media-preview-link:hover .media-crop img { opacity:0.9; transition:opacity 0.2s ease; }
.media-preview-link:hover .audio-preview { background:#e8dfcf; transition:background 0.2s ease; } .media-preview-link:hover .audio-preview { background:#F3F4F6; transition:background 0.2s ease; }
.media-crop { border-radius:12px; }
/* Empty state */ /* Empty state */
.empty-state { text-align:center; padding:4rem 2rem; } .empty-state { text-align:center; padding:4rem 2rem; }
.empty-state .empty-icon { font-size:3rem; margin-bottom:1rem; } .empty-state .empty-icon { font-size:3rem; margin-bottom:1rem; }
.empty-state h2 { color:#20228a; font-size:1.8rem; font-weight:800; margin-bottom:0.5rem; } .empty-state h2 { color:#1F2937; font-size:1.8rem; font-weight:800; margin-bottom:0.5rem; }
.empty-state p { color:#888; max-width:400px; margin:0 auto; line-height:1.6; } .empty-state p { color:#9CA3AF; max-width:400px; margin:0 auto; line-height:1.6; }
/* Footer */ /* Desktop: multi-column masonry */
.site-footer { text-align:center; padding:2rem; border-top:1px solid #eee; margin-top:2rem; } @media(min-width:768px) {
.site-footer p { color:#999; font-size:0.8rem; } .main-grid { max-width:1300px; padding:0 1rem; column-count:4; column-gap:1.2rem; display:block; }
.site-footer a { color:#20228a; text-decoration:none; font-weight:600; } .story-card { break-inside:avoid; margin-bottom:1.2rem; display:inline-block; width:100%; }
.site-footer a:hover { text-decoration:underline; } .card-link { display:inline-block; width:100%; margin-bottom:1.2rem; break-inside:avoid; }
}
@media(max-width:1100px) { .main-grid { column-count:3; } }
@media(max-width:750px) { .main-grid { column-count:2; padding:0 0.7rem; column-gap:0.8rem; } }
@media(max-width:500px) { .main-grid { column-count:1; padding:0 0.8rem; display:flex; flex-direction:column; gap:1rem; } }
/* Responsive masonry column counts */ /* Mobile header tweaks */
@media(max-width:1100px) {
.main-grid { column-count:3; }
}
@media(max-width:750px) {
.main-grid { column-count:2; padding:0 0.7rem; column-gap:0.8rem; }
.story-card { margin-bottom:0.8rem; }
}
@media(max-width:500px) { @media(max-width:500px) {
.main-grid { column-count:1; padding:0 0.8rem; }
.story-card { margin-bottom:1rem; }
.site-header { padding:0.6rem 0.8rem; gap:0.4rem; } .site-header { padding:0.6rem 0.8rem; gap:0.4rem; }
.site-logo-sub { font-size:0.62rem; } .site-logo-sub { font-size:0.62rem; }
.header-right { display:flex; align-items:center; gap:0.3rem; } .header-right { display:flex; align-items:center; gap:0.3rem; }
.header-right a { font-size:0.7rem !important; } .header-right a { font-size:0.7rem !important; }
.submit-bubble { bottom:1rem; right:5rem; } }
.chat-overlay { bottom:5rem; right:0.5rem; width:calc(100vw - 1rem); max-height:60vh; } .chat-overlay { bottom:5rem; right:0.5rem; width:calc(100vw - 1rem); max-height:60vh; }
.chat-bubble { bottom:1rem; right:1rem; } .chat-bubble { bottom:1rem; right:1rem; }
.submit-overlay { bottom:4rem; right:0.5rem; width:calc(100vw - 1rem); max-height:90vh; } .submit-overlay { bottom:4rem; right:0.5rem; width:calc(100vw - 1rem); max-height:90vh; }
} }
.chat-bubble { position:fixed; bottom:1.5rem; right:1.5rem; z-index:9999; .chat-bubble { position:fixed; bottom:1.5rem; right:1.5rem; z-index:9999;
width:56px; height:56px; border-radius:50%; background:#20228a; width:56px; height:56px; border-radius:50%; background:#1F2937;
color:#fff; border:none; cursor:pointer; font-size:1.6rem; color:#F9FAFB; border:none; cursor:pointer; font-size:1.6rem;
box-shadow:0 6px 24px rgba(0,0,0,0.25); transition:transform 0.2s,box-shadow 0.2s,opacity 0.2s; box-shadow:0 6px 24px rgba(0,0,0,0.15); transition:transform 0.2s,box-shadow 0.2s,opacity 0.2s;
display:flex; align-items:center; justify-content:center; } display:flex; align-items:center; justify-content:center; }
.chat-bubble.hidden { opacity:0; pointer-events:none; } .chat-bubble.hidden { opacity:0; pointer-events:none; }
.chat-bubble:hover { transform:scale(1.08); box-shadow:0 8px 32px rgba(0,0,0,0.35); } .chat-bubble:hover { transform:scale(1.08); box-shadow:0 8px 32px rgba(0,0,0,0.2); }
.chat-bubble:active { transform:scale(0.95); } .chat-bubble:active { transform:scale(0.95); }
.chat-bubble .bubble-dot { position:absolute; top:6px; right:6px; width:12px; height:12px; .chat-bubble .bubble-dot { position:absolute; top:6px; right:6px; width:12px; height:12px;
background:#28a745; border-radius:50%; border:2px solid #fff; } background:#10B981; border-radius:50%; border:2px solid #fff; }
.chat-overlay { position:fixed; bottom:5.5rem; right:1.5rem; z-index:10001; .chat-overlay { position:fixed; bottom:5.5rem; right:1.5rem; z-index:10001;
width:380px; max-width:calc(100vw - 2rem); max-height:520px; width:380px; max-width:calc(100vw - 2rem); max-height:520px;
background:#fff; border-radius:18px; box-shadow:0 12px 48px rgba(0,0,0,0.22); background:#fff; border-radius:18px; box-shadow:0 12px 48px rgba(0,0,0,0.12);
display:none; flex-direction:column; overflow:hidden; } display:none; flex-direction:column; overflow:hidden; }
.chat-overlay.open { display:flex; } .chat-overlay.open { display:flex; }
.chat-backdrop { position:fixed; inset:0; z-index:10000; background:rgba(0,0,0,0.25); backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px); display:none; height:100dvh; } .chat-backdrop { position:fixed; inset:0; z-index:10000; background:rgba(0,0,0,0.15); backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px); display:none; height:100dvh; }
.chat-backdrop.open { display:block; } .chat-backdrop.open { display:block; }
.chat-header { background:#20228a; color:#fff; padding:0.9rem 1.2rem; .chat-header { background:#1F2937; color:#F9FAFB; padding:0.9rem 1.2rem;
font-weight:700; font-size:0.9rem; display:flex; align-items:center; justify-content:space-between; } font-weight:700; font-size:0.9rem; display:flex; align-items:center; justify-content:space-between; }
.chat-header button { background:none; border:none; color:#fff; font-size:1.3rem; .chat-header button { background:none; border:none; color:#D1D5DB; font-size:1.3rem;
cursor:pointer; opacity:0.8; transition:opacity 0.15s; padding:0; line-height:1; } cursor:pointer; opacity:0.8; transition:opacity 0.15s; padding:0; line-height:1; }
.chat-header button:hover { opacity:1; } .chat-header button:hover { opacity:1; }
.chat-body { flex:1; overflow-y:auto; padding:1rem; display:flex; flex-direction:column; gap:0.6rem; .chat-body { flex:1; overflow-y:auto; padding:1rem; display:flex; flex-direction:column; gap:0.6rem;
max-height:320px; background:#fafafa; } max-height:320px; background:#F9FAFB; }
.chat-msg { max-width:82%; padding:0.55rem 0.85rem; border-radius:14px; .chat-msg { max-width:82%; padding:0.55rem 0.85rem; border-radius:14px;
font-size:0.82rem; line-height:1.45; word-break:break-word; animation:fadeUp 0.25s ease; } font-size:0.82rem; line-height:1.45; word-break:break-word; animation:fadeUp 0.25s ease; }
.chat-msg.user { align-self:flex-end; background:#20228a; color:#fff; .chat-msg.user { align-self:flex-end; background:#1F2937; color:#F9FAFB;
border-bottom-right-radius:4px; } border-bottom-right-radius:4px; }
.chat-msg.assistant { align-self:flex-start; background:#e9e9eb; color:#1a1a2e; .chat-msg.assistant { align-self:flex-start; background:#E5E7EB; color:#1F2937;
border-bottom-left-radius:4px; } border-bottom-left-radius:4px; }
.chat-msg.typing { background:#e9e9eb; color:#999; font-style:italic; } .chat-msg.typing { background:#E5E7EB; color:#9CA3AF; font-style:italic; }
@keyframes fadeUp { from{opacity:0;transform:translateY(8px);} to{opacity:1;transform:translateY(0);} } @keyframes fadeUp { from{opacity:0;transform:translateY(8px);} to{opacity:1;transform:translateY(0);} }
.chat-footer { padding:0.7rem 0.9rem; border-top:1px solid #eee; display:flex; gap:0.5rem; } .chat-footer { padding:0.7rem 0.9rem; border-top:1px solid #E5E7EB; display:flex; gap:0.5rem; }
.chat-footer input { flex:1; border:1.5px solid #ddd; border-radius:999px; .chat-footer input { flex:1; border:1.5px solid #E5E7EB; border-radius:999px;
padding:0.55rem 1rem; font-size:16px; font-family:inherit; outline:none; padding:0.55rem 1rem; font-size:16px; font-family:inherit; outline:none;
transition:border-color 0.15s; } transition:border-color 0.15s; background:#F9FAFB; }
.chat-footer input:focus { border-color:#20228a; } .chat-footer input:focus { border-color:#6B7280; }
.chat-footer button { background:#20228a; color:#fff; border:none; border-radius:999px; .chat-footer button { background:#1F2937; color:#F9FAFB; border:none; border-radius:999px;
padding:0.55rem 1rem; font-weight:600; font-size:0.82rem; cursor:pointer; padding:0.55rem 1rem; font-weight:600; font-size:0.82rem; cursor:pointer;
transition:background 0.15s; font-family:inherit; } transition:background 0.15s; font-family:inherit; }
.chat-footer button:hover { background:#161e6e; } .chat-footer button:hover { background:#374151; }
.chat-footer button:disabled { opacity:0.5; cursor:default; } .chat-footer button:disabled { opacity:0.5; cursor:default; }
/* Submit Overlay */ /* Submit Overlay */
.submit-bubble { position:fixed; bottom:1.5rem; right:5.5rem; z-index:9999; .submit-bubble { position:fixed; bottom:1.5rem; right:5.5rem; z-index:9999;
width:56px; height:56px; border-radius:50%; background:#20228a; width:56px; height:56px; border-radius:50%; background:#1F2937;
color:#fff; border:none; cursor:pointer; font-size:1.8rem; font-weight:300; line-height:1; color:#F9FAFB; border:none; cursor:pointer; font-size:1.8rem; font-weight:300; line-height:1;
box-shadow:0 6px 24px rgba(0,0,0,0.25); transition:transform 0.2s,box-shadow 0.2s,opacity 0.2s; box-shadow:0 6px 24px rgba(0,0,0,0.15); transition:transform 0.2s,box-shadow 0.2s,opacity 0.2s;
display:flex; align-items:center; justify-content:center; } display:flex; align-items:center; justify-content:center; }
.submit-bubble.hidden { opacity:0; pointer-events:none; } .submit-bubble.hidden { opacity:0; pointer-events:none; }
.submit-bubble:hover { transform:scale(1.08); box-shadow:0 8px 32px rgba(0,0,0,0.35); } .submit-bubble:hover { transform:scale(1.08); box-shadow:0 8px 32px rgba(0,0,0,0.2); }
.submit-bubble:active { transform:scale(0.95); } .submit-bubble:active { transform:scale(0.95); }
.submit-overlay { position:fixed; bottom:5.5rem; right:1.5rem; z-index:10001; .submit-overlay { position:fixed; bottom:5.5rem; right:1.5rem; z-index:10001;
width:400px; max-width:calc(100vw - 2rem); max-height:85vh; width:400px; max-width:calc(100vw - 2rem); max-height:85vh;
background:#fff; border-radius:18px; box-shadow:0 12px 48px rgba(0,0,0,0.22); background:#fff; border-radius:18px; box-shadow:0 12px 48px rgba(0,0,0,0.12);
display:none; flex-direction:column; overflow:hidden; } display:none; flex-direction:column; overflow:hidden; }
.submit-overlay.open { display:flex; } .submit-overlay.open { display:flex; }
.submit-header { background:#20228a; color:#fff; padding:0.9rem 1.2rem; .submit-header { background:#1F2937; color:#F9FAFB; padding:0.9rem 1.2rem;
font-weight:700; font-size:0.9rem; display:flex; align-items:center; justify-content:space-between; } font-weight:700; font-size:0.9rem; display:flex; align-items:center; justify-content:space-between; }
.submit-header button { background:none; border:none; color:#fff; font-size:1.3rem; .submit-header button { background:none; border:none; color:#D1D5DB; font-size:1.3rem;
cursor:pointer; opacity:0.8; padding:0; line-height:1; } cursor:pointer; opacity:0.8; padding:0; line-height:1; }
.submit-header button:hover { opacity:1; } .submit-header button:hover { opacity:1; }
.submit-body { flex:1; overflow-y:auto; padding:1rem; max-height:75vh; background:#fafafa; } .submit-body { flex:1; overflow-y:auto; padding:1rem; max-height:75vh; background:#F9FAFB; }
.submit-body .hint { font-size:0.75rem; color:#888; margin-bottom:1rem; line-height:1.5; } .submit-body .hint { font-size:0.75rem; color:#6B7280; margin-bottom:1rem; line-height:1.5; }
.submit-body label { display:block; font-size:0.7rem; font-weight:600; color:#555; .submit-body label { display:block; font-size:0.7rem; font-weight:600; color:#6B7280;
text-transform:uppercase; letter-spacing:0.03em; margin-bottom:0.2rem; margin-top:0.8rem; } text-transform:uppercase; letter-spacing:0.03em; margin-bottom:0.2rem; margin-top:0.8rem; }
.submit-body label:first-of-type { margin-top:0; } .submit-body label:first-of-type { margin-top:0; }
.submit-body input, .submit-body textarea { width:100%; border:1.5px solid #ddd; .submit-body input, .submit-body textarea { width:100%; border:1.5px solid #E5E7EB;
border-radius:10px; padding:0.55rem 0.8rem; font-size:16px; font-family:inherit; border-radius:10px; padding:0.55rem 0.8rem; font-size:16px; font-family:inherit;
outline:none; transition:border-color 0.15s; } outline:none; transition:border-color 0.15s; background:#fff; }
.submit-body textarea { resize:vertical; min-height:70px; } .submit-body textarea { resize:vertical; min-height:70px; }
.submit-body input:focus, .submit-body textarea:focus { border-color:#20228a; } .submit-body input:focus, .submit-body textarea:focus { border-color:#6B7280; }
.submit-body input[type="file"] { padding:0.4rem 0; border:none; font-size:0.78rem; } .submit-body input[type="file"] { padding:0.4rem 0; border:none; font-size:0.78rem; }
.submit-body .submit-btn { width:100%; background:#20228a; color:#fff; border:none; .submit-body .submit-btn { width:100%; background:#1F2937; color:#F9FAFB; border:none;
border-radius:10px; padding:0.7rem; font-weight:700; font-size:0.88rem; border-radius:10px; padding:0.7rem; font-weight:700; font-size:0.88rem;
cursor:pointer; margin-top:1rem; transition:background 0.15s; font-family:inherit; } cursor:pointer; margin-top:1rem; transition:background 0.15s; font-family:inherit; }
.submit-body .submit-btn:hover { background:#161e6e; } .submit-body .submit-btn:hover { background:#374151; }
.submit-body .submit-btn:disabled { opacity:0.5; cursor:default; } .submit-body .submit-btn:disabled { opacity:0.5; cursor:default; }
.submit-body .status-msg { text-align:center; font-size:0.8rem; margin-top:0.6rem; .submit-body .status-msg { text-align:center; font-size:0.8rem; margin-top:0.6rem;
min-height:1.2rem; } min-height:1.2rem; }
.capture-row { display:flex; gap:1.4rem; margin-top:0.3rem; justify-content:center; align-items:flex-start; } .capture-row { display:flex; gap:1.4rem; margin-top:0.3rem; justify-content:center; align-items:flex-start; }
.capture-item { display:flex; flex-direction:column; align-items:center; gap:0.4rem; } .capture-item { display:flex; flex-direction:column; align-items:center; gap:0.4rem; }
.capture-btn, label.capture-btn { display:flex; align-items:center; justify-content:center; background:#fff; border:2px solid #ddd; border-radius:50%; width:68px; height:68px; cursor:pointer; transition:all 0.15s; -webkit-tap-highlight-color:transparent; touch-action:manipulation; padding:0; } .capture-btn, label.capture-btn { display:flex; align-items:center; justify-content:center; background:#fff; border:2px solid #E5E7EB; border-radius:50%; width:68px; height:68px; cursor:pointer; transition:all 0.15s; -webkit-tap-highlight-color:transparent; touch-action:manipulation; padding:0; }
.capture-btn svg { display:block; } .capture-btn svg { display:block; }
.capture-btn:active { transform:scale(0.92); background:#f0f0f0; border-color:#20228a; } .capture-btn:active { transform:scale(0.92); background:#F3F4F6; border-color:#6B7280; }
.capture-label { font-size:0.62rem; font-weight:600; color:#888; text-transform:uppercase; letter-spacing:0.04em; text-align:center; } .capture-label { font-size:0.62rem; font-weight:600; color:#9CA3AF; text-transform:uppercase; letter-spacing:0.04em; text-align:center; }
/* Login-Dropdown in der Navigation */ /* Login-Dropdown */
.login-dropdown { position:relative; display:inline-block; } .login-dropdown { position:relative; display:inline-block; }
.login-toggle-btn { background:rgba(255,255,255,0.12); border:1.5px solid rgba(255,255,255,0.25); border-radius:8px; color:#fff; padding:0.35rem 0.7rem; font-size:0.78rem; font-weight:600; cursor:pointer; font-family:inherit; transition:all 0.15s; white-space:nowrap; line-height:1.3; } .login-toggle-btn { background:rgba(255,255,255,0.08); border:1px solid rgba(255,255,255,0.12); border-radius:8px; color:#D1D5DB; padding:0.35rem 0.7rem; font-size:0.78rem; font-weight:600; cursor:pointer; font-family:inherit; transition:all 0.15s; white-space:nowrap; line-height:1.3; }
.login-toggle-btn:hover { background:rgba(255,255,255,0.22); border-color:rgba(255,255,255,0.5); } .login-toggle-btn:hover { background:rgba(255,255,255,0.15); border-color:rgba(255,255,255,0.25); }
.login-toggle-btn.active { background:rgba(255,255,255,0.25); border-color:#fff; } .login-toggle-btn.active { background:rgba(255,255,255,0.2); border-color:#D1D5DB; }
.login-dropdown-menu { display:none; position:absolute; right:0; top:110%; background:#fff; border-radius:12px; box-shadow:0 8px 32px rgba(0,0,0,0.18); min-width:240px; z-index:300; overflow:hidden; } .login-dropdown-menu { display:none; position:absolute; right:0; top:110%; background:#fff; border-radius:12px; box-shadow:0 8px 32px rgba(0,0,0,0.1); min-width:240px; z-index:300; overflow:hidden; }
.login-dropdown-menu.open { display:block; animation:fadeDown 0.2s ease; } .login-dropdown-menu.open { display:block; animation:fadeDown 0.2s ease; }
@keyframes fadeDown { from{opacity:0;transform:translateY(-8px);} to{opacity:1;transform:translateY(0);} } @keyframes fadeDown { from{opacity:0;transform:translateY(-8px);} to{opacity:1;transform:translateY(0);} }
.login-dropdown-menu a { display:block; padding:0.65rem 1.1rem; color:#1a1a2e; text-decoration:none; font-size:0.85rem; font-weight:500; transition:background 0.15s; } .login-dropdown-menu a { display:block; padding:0.65rem 1.1rem; color:#1F2937; text-decoration:none; font-size:0.85rem; font-weight:500; transition:background 0.15s; }
.login-dropdown-menu a:hover { background:#f0ede6; } .login-dropdown-menu a:hover { background:#F3F4F6; }
.login-dropdown-form { padding:0.8rem 1rem 0.5rem; } .login-dropdown-form { padding:0.8rem 1rem 0.5rem; }
.login-dropdown-form input { width:100%; padding:0.5rem 0.7rem; margin:0.3rem 0; border:1.5px solid #ddd; border-radius:8px; font-size:0.82rem; font-family:inherit; outline:none; box-sizing:border-box; transition:border-color 0.15s; } .login-dropdown-form input { width:100%; padding:0.5rem 0.7rem; margin:0.3rem 0; border:1.5px solid #E5E7EB; border-radius:8px; font-size:0.82rem; font-family:inherit; outline:none; box-sizing:border-box; transition:border-color 0.15s; background:#fff; }
.login-dropdown-form input:focus { border-color:#20228a; } .login-dropdown-form input:focus { border-color:#6B7280; }
.login-dropdown-form button { width:100%; padding:0.55rem; background:#20228a; color:#fff; border:none; border-radius:8px; font-size:0.82rem; font-weight:600; cursor:pointer; font-family:inherit; margin-top:0.4rem; transition:background 0.15s; } .login-dropdown-form button { width:100%; padding:0.55rem; background:#1F2937; color:#F9FAFB; border:none; border-radius:8px; font-size:0.82rem; font-weight:600; cursor:pointer; font-family:inherit; margin-top:0.4rem; transition:background 0.15s; }
.login-dropdown-form button:hover { background:#161e6e; } .login-dropdown-form button:hover { background:#374151; }
.login-dropdown-register { border-top:1px solid #eee; font-size:0.78rem !important; color:#888 !important; text-align:center; } .login-dropdown-register { border-top:1px solid #E5E7EB; font-size:0.78rem !important; color:#9CA3AF !important; text-align:center; }
.login-dropdown-register:hover { color:#20228a !important; } .login-dropdown-register:hover { color:#6B7280 !important; }
.header-bsn-link { color:#aaa; text-decoration:none; font-size:0.8rem; transition:color 0.2s; } .header-bsn-link { color:#9CA3AF; text-decoration:none; font-size:0.8rem; transition:color 0.2s; }
.header-bsn-link:hover { color:#fff; } .header-bsn-link:hover { color:#F9FAFB; }
/* Welcome Overlay */ /* Welcome Overlay */
.welcome-backdrop { position:fixed; inset:0; z-index:100000; background:rgba(0,0,0,0.4); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); display:none; } .welcome-backdrop { position:fixed; inset:0; z-index:100000; background:rgba(0,0,0,0.3); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); display:none; }
.welcome-backdrop.open { display:flex; align-items:center; justify-content:center; padding:1rem; } .welcome-backdrop.open { display:flex; align-items:center; justify-content:center; padding:1rem; }
.welcome-dialog { background:#fff; border-radius:18px; box-shadow:0 16px 64px rgba(0,0,0,0.25); max-width:480px; width:100%; max-height:90vh; overflow-y:auto; animation:fadeUp 0.3s ease; } .welcome-dialog { background:#fff; border-radius:18px; box-shadow:0 16px 64px rgba(0,0,0,0.15); max-width:480px; width:100%; max-height:90vh; overflow-y:auto; animation:fadeUp 0.3s ease; }
@keyframes fadeUp { from{opacity:0;transform:translateY(20px);} to{opacity:1;transform:translateY(0);} } .welcome-header { background:#1F2937; color:#F9FAFB; padding:1.2rem 1.5rem; border-radius:18px 18px 0 0; font-weight:800; font-size:1.1rem; display:flex; align-items:center; gap:0.5rem; }
.welcome-header { background:#20228a; color:#fff; padding:1.2rem 1.5rem; border-radius:18px 18px 0 0; font-weight:800; font-size:1.1rem; display:flex; align-items:center; gap:0.5rem; } .welcome-body { padding:1.5rem; color:#374151; line-height:1.7; font-size:0.88rem; }
.welcome-body { padding:1.5rem; color:#333; line-height:1.7; font-size:0.88rem; } .welcome-body strong { color:#1F2937; }
.welcome-body strong { color:#20228a; }
.welcome-body .welcome-feature { display:flex; gap:0.6rem; align-items:flex-start; margin:0.7rem 0; } .welcome-body .welcome-feature { display:flex; gap:0.6rem; align-items:flex-start; margin:0.7rem 0; }
.welcome-body .welcome-icon { font-size:1.2rem; flex-shrink:0; margin-top:0.1rem; } .welcome-body .welcome-icon { font-size:1.2rem; flex-shrink:0; margin-top:0.1rem; }
.welcome-footer { padding:0.8rem 1.5rem 1.2rem; border-top:1px solid #f0ede6; display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:0.5rem; } .welcome-footer { padding:0.8rem 1.5rem 1.2rem; border-top:1px solid #E5E7EB; display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:0.5rem; }
.welcome-footer label { font-size:0.78rem; color:#888; display:flex; align-items:center; gap:0.4rem; cursor:pointer; user-select:none; } .welcome-footer label { font-size:0.78rem; color:#9CA3AF; display:flex; align-items:center; gap:0.4rem; cursor:pointer; user-select:none; }
.welcome-footer label input { width:16px; height:16px; accent-color:#20228a; cursor:pointer; } .welcome-footer label input { width:16px; height:16px; accent-color:#1F2937; cursor:pointer; }
.welcome-footer button { background:#20228a; color:#fff; border:none; border-radius:10px; padding:0.55rem 1.4rem; font-size:0.85rem; font-weight:700; cursor:pointer; font-family:inherit; transition:background 0.15s; } .welcome-footer button { background:#1F2937; color:#F9FAFB; border:none; border-radius:10px; padding:0.55rem 1.4rem; font-size:0.85rem; font-weight:700; cursor:pointer; font-family:inherit; transition:background 0.15s; }
.welcome-footer button:hover { background:#161e6e; } .welcome-footer button:hover { background:#374151; }
</style> </style>
</head> </head>
<body> <body>