Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f831fc166e | ||
|
|
8843b1e653 | ||
|
|
d3d31a1689 | ||
|
|
8134c5daf8 |
No files matched your search
+6
-7
@@ -12,11 +12,11 @@ RUN pip3 install --no-cache-dir \
|
||||
pretix-pages \
|
||||
/tmp/pretix-falkenthal-theme
|
||||
|
||||
# 3. Primäre Fallback-Farbwerte (#3b1c4a) im Quellbaum konsistent auf Indigo (#4f46e5) umstellen
|
||||
# (Veranstalter können ihre Shop-Farben weiterhin frei im Web-Interface auf Veranstalter- & Event-Ebene überschreiben)
|
||||
# 3. Primäre Fallback-Farbwerte (#3b1c4a) im Quellbaum auf Royalblau/Indigo umstellen
|
||||
# (Veranstalter können ihre Shop-Farben weiterhin frei im Web-Interface überschreiben)
|
||||
RUN sed -i 's/#3b1c4a/#4f46e5/gI' /pretix/src/pretix/base/settings.py && \
|
||||
find /pretix/src/pretix -type f \( -name "*.scss" -o -name "*.less" -o -name "*.css" \) -exec sed -i \
|
||||
-e 's/#3b1c4a/#4f46e5/gI' \
|
||||
-e 's/#3b1c4a/#2563eb/gI' \
|
||||
-e 's/#5f2977/#4f46e5/gI' \
|
||||
-e 's/#7f4a88/#475569/gI' \
|
||||
-e 's/#8e44ad/#4f46e5/gI' \
|
||||
@@ -34,10 +34,9 @@ RUN rm -rf /pretix/src/pretix/static.dist/CACHE && \
|
||||
|
||||
USER root
|
||||
|
||||
# 6. Vorkompilierte CSS-Dateien bereinigen, Widget-JS prüfen & statische Theme-Assets bereitstellen
|
||||
RUN python3 /tmp/pretix-falkenthal-theme/patch_templates.py && \
|
||||
find /pretix/src/pretix/static.dist -type f -name "*.css" -exec sed -i \
|
||||
-e 's/#3b1c4a/#4f46e5/gI' \
|
||||
# 6. Vorkompilierte CSS-Dateien bereinigen & statische Theme-Assets bereitstellen
|
||||
RUN find /pretix/src/pretix/static.dist -type f -name "*.css" -exec sed -i \
|
||||
-e 's/#3b1c4a/#2563eb/gI' \
|
||||
-e 's/#5f2977/#4f46e5/gI' \
|
||||
-e 's/#7f4a88/#475569/gI' \
|
||||
-e 's/#6c3386/#4f46e5/gI' \
|
||||
|
||||
+17
-197
@@ -1,227 +1,47 @@
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
THEME_REPO_URL = "https://git.falkenthal.me/falkenthal/pretix-falkenthal-theme"
|
||||
PLATFORM_IMPRINT_URL = "https://tickets.falkenthal.me/impressum"
|
||||
PLATFORM_PRIVACY_URL = "https://tickets.falkenthal.me/datenschutz"
|
||||
ASSET_VERSION = "1.8.5"
|
||||
|
||||
control_files = [
|
||||
'/pretix/src/pretix/control/templates/pretixcontrol/base.html',
|
||||
'/pretix/src/pretix/control/templates/pretixcontrol/auth/base.html',
|
||||
]
|
||||
|
||||
platform_footer_html = (
|
||||
'<div class="falkenthal-platform-bar">'
|
||||
'<div class="falkenthal-platform-info">'
|
||||
'<span>Technischer Plattformbetrieb: <strong class="ft-brand">FALKENTHAL</strong></span>'
|
||||
'<span class="ft-sep">·</span>'
|
||||
f'<a href="{PLATFORM_IMPRINT_URL}" target="_blank" rel="noopener">Plattform-Impressum</a>'
|
||||
'<span class="ft-sep">·</span>'
|
||||
f'<a href="{PLATFORM_PRIVACY_URL}" target="_blank" rel="noopener">Plattform-Datenschutz</a>'
|
||||
'<span class="ft-sep">·</span>'
|
||||
f'<a href="{THEME_REPO_URL}" target="_blank" rel="noopener">Theme & Quellcode (AGPLv3)</a>'
|
||||
'</div>'
|
||||
'</div>'
|
||||
'</footer>'
|
||||
footer_Html = (
|
||||
f' · <a href="{THEME_REPO_URL}" target="_blank" rel="noopener">'
|
||||
f'Theme-Plugin (Quellcode)</a></footer>'
|
||||
)
|
||||
|
||||
# 1. Control & Auth Templates patchen (Plattform-Backend: immer Falkenthal-Branding)
|
||||
for p in control_files:
|
||||
if not os.path.exists(p):
|
||||
print(f"ERROR: Expected template not found: {p}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
with open(p, 'r', encoding='utf-8') as f:
|
||||
c = f.read()
|
||||
|
||||
# Standard-Pretix-Favicon im Backend durch Falkenthal-Favicon ersetzen
|
||||
c = re.sub(r'<link[^>]*rel=[\"\'](shortcut )?icon[\"\'][^>]*>', '', c, flags=re.I)
|
||||
|
||||
# Eindeutige Body-Klasse für Auth/Login-Seiten setzen (verhindert CSS-Leaks im normalen Backend)
|
||||
if p.endswith('auth/base.html') and 'falkenthal-auth-body' not in c:
|
||||
if '<body' in c:
|
||||
c = re.sub(
|
||||
r'<body([^>]*)class=["\']([^"\']*)["\']',
|
||||
r'<body\1class="\2 falkenthal-auth-body"',
|
||||
c,
|
||||
count=1,
|
||||
flags=re.I,
|
||||
)
|
||||
if 'falkenthal-auth-body' not in c:
|
||||
c = re.sub(r'<body', '<body class="falkenthal-auth-body"', c, count=1, flags=re.I)
|
||||
|
||||
if '/static/whitelabel/control.css' not in c:
|
||||
if '</head>' not in c:
|
||||
print(f"ERROR: </head> tag not found in {p}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
c = c.replace(
|
||||
'</head>',
|
||||
f'<link rel="icon" type="image/svg+xml" href="/static/whitelabel/favicon.svg?v={ASSET_VERSION}">'
|
||||
f'<link rel="shortcut icon" href="/static/whitelabel/favicon.svg?v={ASSET_VERSION}">'
|
||||
f'<link rel="stylesheet" type="text/css" href="/static/whitelabel/control.css?v={ASSET_VERSION}"></head>'
|
||||
'<link rel="icon" type="image/svg+xml" href="/static/whitelabel/favicon.svg?v=7">'
|
||||
'<link rel="shortcut icon" href="/static/whitelabel/favicon.svg?v=7">'
|
||||
'<link rel="stylesheet" type="text/css" href="/static/whitelabel/control.css?v=7"></head>'
|
||||
)
|
||||
|
||||
if 'falkenthal-platform-bar' not in c:
|
||||
if '</footer>' not in c:
|
||||
print(f"ERROR: </footer> tag not found in {p}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
c = c.replace('</footer>', platform_footer_html)
|
||||
|
||||
if THEME_REPO_URL not in c:
|
||||
c = c.replace('</footer>', footer_Html)
|
||||
with open(p, 'w', encoding='utf-8') as f:
|
||||
f.write(c)
|
||||
|
||||
# 2. Presale Template patchen (Ticketshop: Veranstalter-Favicons respektieren, Fallback = Falkenthal)
|
||||
presale_file = '/pretix/src/pretix/presale/templates/pretixpresale/base.html'
|
||||
if not os.path.exists(presale_file):
|
||||
print(f"ERROR: Expected template not found: {presale_file}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
with open(presale_file, 'r', encoding='utf-8') as f:
|
||||
c = f.read()
|
||||
|
||||
# Nur die statischen Standard-Pretix-Favicon-Fallbacks ersetzen, damit individuelle
|
||||
# Veranstalter-/Event-Favicons ({% if request.event.settings.favicon %}) erhalten bleiben!
|
||||
c = re.sub(
|
||||
r'<link[^>]*rel=[\"\'](shortcut )?icon[\"\'][^>]*static\s+[\"\']pretixbase/img/favicon[^\"\']*[\"\'][^>]*>',
|
||||
'',
|
||||
c,
|
||||
flags=re.I,
|
||||
)
|
||||
# Falls in einem {% else %}-Zweig der Standard-Favicon-Block nun leer wäre oder direkt vor </head>:
|
||||
c = re.sub(r'<link[^>]*rel=[\"\'](shortcut )?icon[\"\'][^>]*>', '', c, flags=re.I)
|
||||
if '/static/whitelabel/presale.css' not in c:
|
||||
if '</head>' not in c:
|
||||
print(f"ERROR: </head> tag not found in {presale_file}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
presale_head_inject = (
|
||||
'{% if not request.event or not request.event.settings.favicon %}'
|
||||
f'<link rel="icon" type="image/svg+xml" href="/static/whitelabel/favicon.svg?v={ASSET_VERSION}">'
|
||||
f'<link rel="shortcut icon" href="/static/whitelabel/favicon.svg?v={ASSET_VERSION}">'
|
||||
'{% endif %}'
|
||||
f'<link rel="stylesheet" type="text/css" href="/static/whitelabel/presale.css?v={ASSET_VERSION}"></head>'
|
||||
c = c.replace(
|
||||
'</head>',
|
||||
'<link rel="icon" type="image/svg+xml" href="/static/whitelabel/favicon.svg?v=7">'
|
||||
'<link rel="shortcut icon" href="/static/whitelabel/favicon.svg?v=7">'
|
||||
'<link rel="stylesheet" type="text/css" href="/static/whitelabel/presale.css?v=7"></head>'
|
||||
)
|
||||
c = c.replace('</head>', presale_head_inject)
|
||||
|
||||
if 'falkenthal-platform-bar' not in c:
|
||||
if '</footer>' not in c:
|
||||
print(f"ERROR: </footer> tag not found in {presale_file}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
c = c.replace('</footer>', platform_footer_html)
|
||||
|
||||
if THEME_REPO_URL not in c:
|
||||
c = c.replace('</footer>', footer_Html)
|
||||
with open(presale_file, 'w', encoding='utf-8') as f:
|
||||
f.write(c)
|
||||
|
||||
# 3. Globale Fehlerseiten (400, 403, 404, 500, 503) mit Plattform-Rechtstexten ausstatten
|
||||
error_templates_dir = '/pretix/src/pretix/base/templates'
|
||||
for err_name in ['400.html', '403.html', '403_csrf.html', '404.html', '500.html', '503.html']:
|
||||
err_path = os.path.join(error_templates_dir, err_name)
|
||||
if os.path.exists(err_path):
|
||||
with open(err_path, 'r', encoding='utf-8') as f:
|
||||
ec = f.read()
|
||||
if 'falkenthal-platform-bar' not in ec and '</body>' in ec:
|
||||
error_footer = (
|
||||
'<div class="falkenthal-platform-bar" style="margin-top:32px;padding:16px 12px;'
|
||||
'border-top:1px solid rgba(148,163,184,0.25);font-family:system-ui,-apple-system,sans-serif;'
|
||||
'font-size:12px;color:#64748b;text-align:center;line-height:1.6;">'
|
||||
'<span>Technischer Plattformbetrieb: <strong style="color:#334155;">FALKENTHAL</strong></span>'
|
||||
' · '
|
||||
f'<a href="{PLATFORM_IMPRINT_URL}" target="_blank" rel="noopener" style="color:#64748b;text-decoration:underline;">Plattform-Impressum</a>'
|
||||
' · '
|
||||
f'<a href="{PLATFORM_PRIVACY_URL}" target="_blank" rel="noopener" style="color:#64748b;text-decoration:underline;">Plattform-Datenschutz</a>'
|
||||
' · '
|
||||
f'<a href="{THEME_REPO_URL}" target="_blank" rel="noopener" style="color:#64748b;text-decoration:underline;">Theme & Quellcode (AGPLv3)</a>'
|
||||
'</div></body>'
|
||||
)
|
||||
ec = ec.replace('</body>', error_footer)
|
||||
with open(err_path, 'w', encoding='utf-8') as f:
|
||||
f.write(ec)
|
||||
|
||||
# 4. Eingebettetes Pretix-Widget (/widget/v1.*.js & widget.py):
|
||||
# Einheitliche Plattform-Pflichtangaben garantiert in jedem <pretix-widget> (auch auf Jimdo & bei leeren Events)!
|
||||
widget_platform_bar_js = r"""
|
||||
;(function(){
|
||||
if (typeof document === 'undefined' || window.__falkenthalWidgetPatched) return;
|
||||
window.__falkenthalWidgetPatched = true;
|
||||
var BAR_HTML = '<span>Technischer Plattformbetrieb: <strong style="font-weight:600;">FALKENTHAL</strong></span>' +
|
||||
' · <a href="https://tickets.falkenthal.me/impressum" target="_blank" rel="noopener" style="color:inherit;text-decoration:underline;">Plattform-Impressum</a>' +
|
||||
' · <a href="https://tickets.falkenthal.me/datenschutz" target="_blank" rel="noopener" style="color:inherit;text-decoration:underline;">Plattform-Datenschutz</a>' +
|
||||
' · <a href="https://git.falkenthal.me/falkenthal/pretix-falkenthal-theme" target="_blank" rel="noopener" style="color:inherit;text-decoration:underline;">Theme & Quellcode (AGPLv3)</a>';
|
||||
function injectWidgetBar() {
|
||||
var containers = document.querySelectorAll('.pretix-widget-attribution, .pretix-widget');
|
||||
for (var i = 0; i < containers.length; i++) {
|
||||
var el = containers[i];
|
||||
var widgetRoot = el.classList.contains('pretix-widget') ? el : el.closest('.pretix-widget');
|
||||
var checkTarget = widgetRoot || el;
|
||||
if (checkTarget.querySelector('.pretix-widget-falkenthal-bar')) continue;
|
||||
var target = checkTarget.querySelector('.pretix-widget-attribution') || checkTarget;
|
||||
var bar = document.createElement('div');
|
||||
bar.className = 'pretix-widget-falkenthal-bar';
|
||||
bar.style.cssText = 'margin-top:8px;padding-top:8px;border-top:1px solid rgba(128,128,128,0.22);font-size:11px;line-height:1.5;text-align:center;opacity:0.85;clear:both;';
|
||||
bar.innerHTML = BAR_HTML;
|
||||
target.appendChild(bar);
|
||||
}
|
||||
}
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', injectWidgetBar);
|
||||
} else {
|
||||
injectWidgetBar();
|
||||
}
|
||||
if (typeof MutationObserver !== 'undefined') {
|
||||
var obs = new MutationObserver(function() { injectWidgetBar(); });
|
||||
var startObs = function() {
|
||||
if (document.body) obs.observe(document.body, { childList: true, subtree: true });
|
||||
};
|
||||
if (document.body) startObs();
|
||||
else document.addEventListener('DOMContentLoaded', startObs);
|
||||
}
|
||||
setInterval(injectWidgetBar, 1000);
|
||||
})();
|
||||
"""
|
||||
|
||||
# 4a. Alle statischen Widget-JS-Dateien im gesamten Pretix-Baum finden (z.B. ui/widget.js, widget/*.js, static.dist)
|
||||
widget_js_candidates = (
|
||||
glob.glob('/pretix/src/pretix/presale/static/**/*widget*.js', recursive=True)
|
||||
+ glob.glob('/pretix/src/pretix/static.dist/**/*widget*.js', recursive=True)
|
||||
)
|
||||
patched_js_count = 0
|
||||
for wjs in set(widget_js_candidates):
|
||||
if os.path.isfile(wjs) and not wjs.endswith('.min.js.map'):
|
||||
with open(wjs, 'r', encoding='utf-8') as f:
|
||||
wc = f.read()
|
||||
if '__falkenthalWidgetPatched' not in wc:
|
||||
with open(wjs, 'a', encoding='utf-8') as f:
|
||||
f.write('\n' + widget_platform_bar_js)
|
||||
patched_js_count += 1
|
||||
|
||||
# 4b. Zusätzlich direkt die Django-View /pretix/src/pretix/presale/views/widget.py patchen,
|
||||
# da Pretix /widget/v1.de.js dynamisch über diese View generiert, im Dateisystem speichert und ausliefert!
|
||||
widget_view_py = '/pretix/src/pretix/presale/views/widget.py'
|
||||
if os.path.exists(widget_view_py):
|
||||
with open(widget_view_py, 'r', encoding='utf-8') as f:
|
||||
wpy = f.read()
|
||||
if '__falkenthalWidgetPatched' not in wpy:
|
||||
wpy_patch = (
|
||||
f"\n\n# --- FALKENTHAL PLATFORM LEGAL BAR INJECTION ---\n"
|
||||
f"_FALKENTHAL_WIDGET_JS = {repr(widget_platform_bar_js)}\n"
|
||||
f"if 'generate_widget_js' in globals():\n"
|
||||
f" _orig_generate_widget_js = generate_widget_js\n"
|
||||
f" def generate_widget_js(lang):\n"
|
||||
f" code = _orig_generate_widget_js(lang)\n"
|
||||
f" if '__falkenthalWidgetPatched' not in code:\n"
|
||||
f" code = code + '\\n' + _FALKENTHAL_WIDGET_JS\n"
|
||||
f" return code\n"
|
||||
f"if 'widget_js' in globals():\n"
|
||||
f" _orig_widget_js = widget_js\n"
|
||||
f" def widget_js(request, *args, **kwargs):\n"
|
||||
f" resp = _orig_widget_js(request, *args, **kwargs)\n"
|
||||
f" if hasattr(resp, 'content') and b'__falkenthalWidgetPatched' not in resp.content:\n"
|
||||
f" resp.content = resp.content + _FALKENTHAL_WIDGET_JS.encode('utf-8')\n"
|
||||
f" return resp\n"
|
||||
)
|
||||
with open(widget_view_py, 'a', encoding='utf-8') as f:
|
||||
f.write(wpy_patch)
|
||||
|
||||
print(f"Pretix templates and widget assets ({patched_js_count} JS files + widget.py) patched and verified successfully (v{ASSET_VERSION}).")
|
||||
|
||||
print("Pretix templates patched successfully (v1.7.3).")
|
||||
@@ -13,7 +13,7 @@ class WhiteLabelApp(AppConfig):
|
||||
"Custom Slate & Blue-Violet theme plugin for pretix control and presale UI."
|
||||
)
|
||||
visible = False
|
||||
version = "1.8.5"
|
||||
version = "1.7.2"
|
||||
category = "CUSTOMIZATION"
|
||||
|
||||
|
||||
|
||||
+146
-15
@@ -1,17 +1,148 @@
|
||||
"""
|
||||
Pretix signal receivers for pretix-falkenthal-theme (v1.8.5).
|
||||
FALKENTHAL_INJECTION = """
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap" rel="stylesheet">
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" type="text/css" href="{css_url}?v=1.7.3">
|
||||
|
||||
Hinweis zur Architektur:
|
||||
Die Plattform-Pflichtangaben (Plattform-Impressum, Plattform-Datenschutz sowie
|
||||
der AGPLv3-Quellcode-Nachweis) werden server-seitig über patch_templates.py
|
||||
beim Docker-Build direkt in die Basis-Templates (pretixcontrol, pretixpresale
|
||||
sowie globale Fehlerseiten 400/403/404/500/503) eingebettet und durch Build-Checks
|
||||
verifiziert.
|
||||
<style>
|
||||
/* Grundlegendes Layout-Fixing für Kalender- und Veranstalter-Übersichten */
|
||||
body {
|
||||
background-color: #03060d !important;
|
||||
color: #cbd5e1 !important;
|
||||
font-family: 'Plus Jakarta Sans', sans-serif !important;
|
||||
}
|
||||
|
||||
Dadurch wird eine saubere 2-Ebenen-Trennung gewährleistet:
|
||||
- Ebene 1 (Veranstalter / Event): Nativer Pretix-Footer mit den individuellen
|
||||
Rechtstexten des jeweiligen Veranstalters (Impressum, Datenschutz, AGB),
|
||||
individuelle Veranstalter-Farben (inkl. Dark-Mode-Support) & Event-Favicons.
|
||||
- Ebene 2 (Plattform): Falkenthal-Plattform-Leiste (.falkenthal-platform-bar)
|
||||
mit den Angaben des technischen Plattform-Betreibers und Fallback-Favicon.
|
||||
"""
|
||||
/* Container-Korrektur, damit nichts oben verschwimmt */
|
||||
.container, .container-fluid, .content {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
/* Kalender- und Tabellen-Wrapper in den Glassmorphism-Look hüllen */
|
||||
.tab-content, .panel, .card, table.table, .calendar-table {
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.04) 0%, rgba(255, 255, 255, 0.01) 100%) !important;
|
||||
backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(0, 210, 255, 0.12) !important;
|
||||
border-radius: 12px;
|
||||
color: #e2e8f0 !important;
|
||||
}
|
||||
|
||||
/* Tabellen- und Textfarben in der Übersicht anpassen */
|
||||
table th, table td {
|
||||
border-color: rgba(255, 255, 255, 0.06) !important;
|
||||
color: #cbd5e1 !important;
|
||||
}
|
||||
|
||||
/* Navigations-Buttons (List, Week, Month, Day) optisch anpassen */
|
||||
.nav-pills > li > a, .btn-default, .btn-group .btn {
|
||||
background: rgba(255, 255, 255, 0.03) !important;
|
||||
border: 1px solid rgba(0, 210, 255, 0.15) !important;
|
||||
color: #94a3b8 !important;
|
||||
}
|
||||
|
||||
.nav-pills > li.active > a, .btn-primary {
|
||||
background: rgba(0, 210, 255, 0.15) !important;
|
||||
border-color: #00d2ff !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
/* Veranstalter-Badge im Footer */
|
||||
.falkenthal-organizer-badge {
|
||||
display: inline-block;
|
||||
font-family: 'Space Grotesk', monospace;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: #00d2ff;
|
||||
background: rgba(0, 210, 255, 0.08);
|
||||
border: 1px solid rgba(0, 210, 255, 0.2);
|
||||
border-radius: 4px;
|
||||
padding: 1px 6px;
|
||||
margin-right: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Untere Plattform-Leiste (System-Ebene) */
|
||||
.falkenthal-platform-bar {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 20px;
|
||||
padding: 14px 16px;
|
||||
border-top: 1px solid rgba(0, 210, 255, 0.12);
|
||||
text-align: center;
|
||||
font-family: 'Plus Jakarta Sans', sans-serif;
|
||||
font-size: 12px;
|
||||
color: #64748b;
|
||||
line-height: 1.6;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar .ft-brand {
|
||||
font-family: 'Space Grotesk', sans-serif;
|
||||
color: #94a3b8;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar a {
|
||||
color: #94a3b8 !important;
|
||||
text-decoration: none !important;
|
||||
transition: color 0.2s ease, text-shadow 0.2s ease;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar a:hover {
|
||||
color: #00d2ff !important;
|
||||
text-shadow: 0 0 10px rgba(0, 210, 255, 0.4);
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar .ft-sep {
|
||||
margin: 0 6px;
|
||||
color: #334155;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// Vorherige Leisten bereinigen
|
||||
document.querySelectorAll('.falkenthal-platform-bar').forEach(function(el) {
|
||||
el.remove();
|
||||
});
|
||||
|
||||
var footer = document.querySelector('footer, .footer, #footer');
|
||||
if (!footer) {
|
||||
footer = document.querySelector('body');
|
||||
}
|
||||
|
||||
if (footer) {
|
||||
// Veranstalter-Badge bei echten Veranstalter-Links einfügen
|
||||
var orgLinks = Array.from(footer.querySelectorAll('a')).filter(function(a) {
|
||||
return a.offsetParent !== null &&
|
||||
!a.href.includes('agpl_source') &&
|
||||
!a.href.includes('pretix.eu') &&
|
||||
!a.href.includes('falkenthal.me');
|
||||
});
|
||||
|
||||
if (orgLinks.length > 0 && !footer.querySelector('.falkenthal-organizer-badge')) {
|
||||
var badge = document.createElement('span');
|
||||
badge.className = 'falkenthal-organizer-badge';
|
||||
badge.textContent = 'Veranstalter';
|
||||
orgLinks[0].parentNode.insertBefore(badge, orgLinks[0]);
|
||||
}
|
||||
|
||||
// Saubere Plattform-Leiste anhängen
|
||||
var bar = document.createElement('div');
|
||||
bar.className = 'falkenthal-platform-bar';
|
||||
bar.innerHTML =
|
||||
'<span>Technischer Plattformbetrieb: <strong class="ft-brand">FALKENTHAL</strong></span>' +
|
||||
'<span class="ft-sep">·</span>' +
|
||||
'<a href="https://tickets.falkenthal.me/impressum" target="_blank" rel="noopener">Plattform-Impressum</a>' +
|
||||
'<span class="ft-sep">·</span>' +
|
||||
'<a href="https://tickets.falkenthal.me/datenschutz" target="_blank" rel="noopener">Plattform-Datenschutz</a>' +
|
||||
'<span class="ft-sep">·</span>' +
|
||||
'<a href="https://tickets.falkenthal.me/agpl_source">Quellcode (AGPLv3)</a>';
|
||||
|
||||
footer.appendChild(bar);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
"""
|
||||
@@ -1,5 +1,5 @@
|
||||
/* ==========================================================================
|
||||
FALKENTHAL ADMIN BACKEND & LOGIN THEME (control.css - v1.8.5)
|
||||
FALKENTHAL ADMIN BACKEND & LOGIN THEME (control.css - v7)
|
||||
========================================================================== */
|
||||
|
||||
:root {
|
||||
@@ -11,14 +11,13 @@
|
||||
--fk-text-main: #0f172a;
|
||||
--fk-text-secondary: #334155;
|
||||
--fk-text-muted: #64748b;
|
||||
--fk-cyan: #38bdf8;
|
||||
--fk-cyan: #00e5ff;
|
||||
--fk-blue: #2563eb;
|
||||
--fk-indigo: #4f46e5;
|
||||
--fk-indigo-light: #818cf8;
|
||||
--fk-purple: #6366f1;
|
||||
--fk-purple: #7c3aed;
|
||||
--fk-border: #e2e8f0;
|
||||
--fk-gradient-primary: linear-gradient(135deg, #2563eb 0%, #4f46e5 65%, #6366f1 100%);
|
||||
--fk-gradient-hover: linear-gradient(135deg, #1d4ed8 0%, #4338ca 65%, #4f46e5 100%);
|
||||
--fk-gradient-primary: linear-gradient(135deg, #2563eb 0%, #4f46e5 55%, #7c3aed 100%);
|
||||
--fk-gradient-hover: linear-gradient(135deg, #1d4ed8 0%, #4338ca 55%, #6d28d9 100%);
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -63,7 +62,7 @@ nav.navbar-inverse {
|
||||
a.navbar-brand {
|
||||
font-size: 0 !important;
|
||||
color: transparent !important;
|
||||
background-image: url('/static/whitelabel/logo.svg?v=1.8.5') !important;
|
||||
background-image: url('/static/whitelabel/logo.svg?v=7') !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-position: 14px center !important;
|
||||
background-size: auto 34px !important;
|
||||
@@ -168,7 +167,7 @@ a.navbar-brand {
|
||||
}
|
||||
|
||||
.sidebar .context-selector .context-name,
|
||||
.sidebar .context-selector .context-indicator span:not(.fa-stack):not(.caret) {
|
||||
.sidebar .context-selector span:not(.fa-stack):not(.caret) {
|
||||
color: #f8fafc !important;
|
||||
font-weight: 600 !important;
|
||||
display: block !important;
|
||||
@@ -188,21 +187,12 @@ a.navbar-brand {
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
/* Kleines Dreieck (Caret) rechts sauber als echtes Dreieck ausrichten (verhindert "admin@falkenthal.me-" Strich) */
|
||||
.sidebar .context-selector span.caret,
|
||||
/* Kleines Dreieck (Caret) rechts sauber ausrichten */
|
||||
.sidebar .context-selector .caret {
|
||||
flex-shrink: 0 !important;
|
||||
display: inline-block !important;
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
overflow: visible !important;
|
||||
vertical-align: middle !important;
|
||||
border-top: 5px solid #94a3b8 !important;
|
||||
border-right: 4px solid transparent !important;
|
||||
border-left: 4px solid transparent !important;
|
||||
border-bottom: 0 !important;
|
||||
margin-left: 6px !important;
|
||||
background: transparent !important;
|
||||
color: #94a3b8 !important;
|
||||
border-top-color: #94a3b8 !important;
|
||||
margin-left: 4px !important;
|
||||
}
|
||||
|
||||
/* Aufklappendes Dropdown-Menü der Nutzerauswahl */
|
||||
@@ -271,7 +261,7 @@ a.navbar-brand {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* --- C) HAUPTMENÜPUNKTE (Flache Spezifität & harmonische Indigo-Slate-Farbabstimmung) --- */
|
||||
/* --- C) HAUPTMENÜPUNKTE (Flache Spezifität für garantierte Aktiv-Kontraste) --- */
|
||||
#side-menu > li > a {
|
||||
color: #cbd5e1 !important;
|
||||
font-weight: 500 !important;
|
||||
@@ -284,7 +274,7 @@ a.navbar-brand {
|
||||
|
||||
#side-menu > li > a i.fa,
|
||||
#side-menu > li > a span.fa:not(.arrow) {
|
||||
color: #94a3b8 !important;
|
||||
color: #60a5fa !important;
|
||||
width: 20px !important;
|
||||
text-align: center !important;
|
||||
margin-right: 8px !important;
|
||||
@@ -294,13 +284,13 @@ a.navbar-brand {
|
||||
/* Hover auf inaktiven Menüpunkten */
|
||||
#side-menu > li > a:hover,
|
||||
#side-menu > li > a:focus {
|
||||
background-color: rgba(255, 255, 255, 0.07) !important;
|
||||
background-color: rgba(255, 255, 255, 0.08) !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
#side-menu > li > a:hover i.fa,
|
||||
#side-menu > li > a:hover span.fa:not(.arrow) {
|
||||
color: #818cf8 !important;
|
||||
color: var(--fk-cyan) !important;
|
||||
}
|
||||
|
||||
/* Geöffneter Eltern-Menüpunkt (z.B. "Einstellungen", wenn Unterpunkt aktiv ist) */
|
||||
@@ -312,7 +302,7 @@ a.navbar-brand {
|
||||
|
||||
#side-menu > li.active > a i.fa,
|
||||
#side-menu > li.active > a span.fa:not(.arrow) {
|
||||
color: #818cf8 !important;
|
||||
color: var(--fk-cyan) !important;
|
||||
}
|
||||
|
||||
/* AKTIVER HAUPTMENÜPUNKT (z.B. "Übersicht") -> Garantiert weiße Schrift & weißes Icon! */
|
||||
@@ -321,7 +311,7 @@ a.navbar-brand {
|
||||
background: var(--fk-gradient-primary) !important;
|
||||
color: #ffffff !important;
|
||||
font-weight: 600 !important;
|
||||
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.35) !important;
|
||||
box-shadow: 0 4px 14px rgba(79, 70, 229, 0.4) !important;
|
||||
}
|
||||
|
||||
#side-menu > li > a.active i.fa,
|
||||
@@ -466,95 +456,50 @@ fieldset legend {
|
||||
border-bottom: 2px solid var(--fk-indigo) !important;
|
||||
}
|
||||
|
||||
/* --- DASHBOARD-KACHELN & VERANSTALTUNGS-ÜBERSICHT (Saubere Cards ohne Box-in-Box-Fehler) --- */
|
||||
/* --- DASHBOARD-KACHELN (Doppelte graue Außenkästen entfernen & lesbare Typografie) --- */
|
||||
|
||||
/* 1. Äußeren .widget-container restlos neutralisieren (behebt die grauen Ecken/Artefakte links!) */
|
||||
.dashboard,
|
||||
.event-dashboard {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.dashboard .widget-container,
|
||||
.event-dashboard .widget-container,
|
||||
.widget-container {
|
||||
background: transparent !important;
|
||||
background-color: transparent !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.dashboard .widget-container::before,
|
||||
.dashboard .widget-container::after,
|
||||
.event-dashboard .widget-container::before,
|
||||
.event-dashboard .widget-container::after,
|
||||
.widget-container::before,
|
||||
.widget-container::after {
|
||||
display: none !important;
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
/* 2. Innere .widget-Box als einzige saubere weiße Card definieren (mit 100% Breite für Kinder!) */
|
||||
/* 1. Äußere Widget-Box als einzige saubere weiße Card definieren */
|
||||
.dashboard .widget-container .widget,
|
||||
.event-dashboard .widget-container .widget,
|
||||
.widget-container > .widget {
|
||||
background: var(--fk-card-bg) !important;
|
||||
.event-dashboard .widget-container .widget {
|
||||
background-color: var(--fk-card-bg) !important;
|
||||
border: 1px solid var(--fk-border) !important;
|
||||
border-radius: 10px !important;
|
||||
box-shadow: 0 1px 4px rgba(15, 23, 42, 0.04) !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: 0 2px 6px rgba(15, 23, 42, 0.04) !important;
|
||||
padding: 20px 16px !important;
|
||||
min-height: 122px !important;
|
||||
height: calc(100% - 15px) !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
justify-content: center !important;
|
||||
align-items: stretch !important;
|
||||
text-align: center !important;
|
||||
overflow: hidden !important;
|
||||
transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease !important;
|
||||
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.dashboard .widget-container .widget::before,
|
||||
.dashboard .widget-container .widget::after,
|
||||
.event-dashboard .widget-container .widget::before,
|
||||
.event-dashboard .widget-container .widget::after {
|
||||
.dashboard .widget-container .widget::after {
|
||||
display: none !important;
|
||||
content: none !important;
|
||||
}
|
||||
|
||||
.dashboard .widget-container a.widget:hover,
|
||||
.event-dashboard .widget-container a.widget:hover,
|
||||
.dashboard .widget-container .widget:hover {
|
||||
transform: translateY(-1px) !important;
|
||||
box-shadow: 0 8px 18px -4px rgba(37, 99, 235, 0.10) !important;
|
||||
transform: translateY(-2px) !important;
|
||||
box-shadow: 0 10px 22px -5px rgba(37, 99, 235, 0.12) !important;
|
||||
border-color: #93c5fd !important;
|
||||
}
|
||||
|
||||
/* 3. Innere .numwidget-Box komplett neutralisieren (verhindert Box-in-Box-Effekt) */
|
||||
/* 2. Innere .numwidget-Box komplett neutralisieren (verhindert Box-in-Box-Effekt) */
|
||||
.dashboard .widget .numwidget,
|
||||
.event-dashboard .widget .numwidget,
|
||||
.numwidget {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
padding: 0 !important;
|
||||
margin: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* 4. Zahlen dunkel & kontraststark, Labels dezent grau statt alles blau */
|
||||
/* 3. Zahlen dunkel & kontraststark, Labels dezent grau statt alles blau */
|
||||
.dashboard .widget .numwidget .num,
|
||||
.numwidget .num {
|
||||
color: var(--fk-text-main) !important;
|
||||
font-weight: 700 !important;
|
||||
font-size: 30px !important;
|
||||
font-size: 32px !important;
|
||||
line-height: 1.2 !important;
|
||||
display: block !important;
|
||||
margin-bottom: 6px !important;
|
||||
transition: color 0.15s ease !important;
|
||||
}
|
||||
|
||||
.dashboard .widget:hover .numwidget .num {
|
||||
@@ -565,134 +510,40 @@ fieldset legend {
|
||||
.numwidget .text {
|
||||
color: var(--fk-text-muted) !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 13px !important;
|
||||
font-size: 13.5px !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* 5. Veranstaltungs-Kacheln auf der globalen Start-Übersicht ("Ihre nächsten Veranstaltungen"):
|
||||
Kompakte Typografie in der oberen Hälfte, Statusleiste bündig unten & identische Kachelhöhe! */
|
||||
.dashboard .widget-container .widget:has(.bottomrow),
|
||||
.dashboard .widget-container .widget:has(.event),
|
||||
.dashboard .widget-container .widget.event,
|
||||
.dashboard > .event,
|
||||
.dashboard .widget-container > .event {
|
||||
padding: 0 !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
justify-content: flex-start !important;
|
||||
align-items: stretch !important;
|
||||
text-align: center !important;
|
||||
/* Event-Kacheln auf der globalen Start-Übersicht */
|
||||
.dashboard .event {
|
||||
background-color: var(--fk-card-bg) !important;
|
||||
border: 1px solid var(--fk-border) !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: 0 2px 6px rgba(15, 23, 42, 0.04) !important;
|
||||
overflow: hidden !important;
|
||||
transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease !important;
|
||||
}
|
||||
|
||||
.dashboard .widget .event {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
border-radius: 0 !important;
|
||||
box-shadow: none !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
justify-content: flex-start !important;
|
||||
flex: 1 1 auto !important;
|
||||
}
|
||||
|
||||
/* Oberer Textbereich der Event-Kachel (Name, Datum, Uhrzeit kompakt zusammenhalten statt auseinanderzureißen) */
|
||||
.dashboard .event .toprow,
|
||||
.dashboard .widget:has(.bottomrow) > a:first-child {
|
||||
.dashboard .event > a {
|
||||
border: none !important;
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
width: 100% !important;
|
||||
padding: 20px 18px 14px 18px !important;
|
||||
margin: 0 !important;
|
||||
flex: 1 1 auto !important;
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
justify-content: center !important;
|
||||
align-items: center !important;
|
||||
gap: 4px !important;
|
||||
text-align: center !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* Falls Name, Datum und Uhrzeit direkte Kinder von a.widget oder .event sind (ohne .toprow Wrapper) */
|
||||
.dashboard .widget .name,
|
||||
.dashboard .event:hover {
|
||||
transform: translateY(-2px) !important;
|
||||
box-shadow: 0 10px 25px -5px rgba(37, 99, 235, 0.14) !important;
|
||||
border-color: #60a5fa !important;
|
||||
}
|
||||
|
||||
.dashboard .event .name {
|
||||
color: var(--fk-text-main) !important;
|
||||
font-weight: 700 !important;
|
||||
font-size: 16.5px !important;
|
||||
line-height: 1.3 !important;
|
||||
margin: 18px 16px 4px 16px !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.dashboard .event .toprow .name {
|
||||
margin: 0 0 4px 0 !important;
|
||||
}
|
||||
|
||||
.dashboard .widget .daterange,
|
||||
.dashboard .event .daterange {
|
||||
color: var(--fk-text-secondary) !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
line-height: 1.35 !important;
|
||||
margin: 0 16px 2px 16px !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.dashboard .widget .times,
|
||||
.dashboard .event .times {
|
||||
color: var(--fk-text-muted) !important;
|
||||
font-weight: 400 !important;
|
||||
font-size: 13px !important;
|
||||
line-height: 1.3 !important;
|
||||
margin: 0 16px 14px 16px !important;
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
/* Untere Statusleiste ("0 Bestellungen" | "Shop deaktiviert") immer mit margin-top: auto an den unteren Rand drücken */
|
||||
.dashboard .widget .bottomrow,
|
||||
.dashboard .event .bottomrow {
|
||||
width: 100% !important;
|
||||
margin: auto 0 0 0 !important;
|
||||
display: flex !important;
|
||||
align-items: stretch !important;
|
||||
border-top: 1px solid var(--fk-border) !important;
|
||||
min-height: 38px !important;
|
||||
}
|
||||
|
||||
.dashboard .widget .bottomrow > a,
|
||||
.dashboard .widget .bottomrow > div,
|
||||
.dashboard .widget .bottomrow > span,
|
||||
.dashboard .event .bottomrow > a,
|
||||
.dashboard .event .bottomrow > div,
|
||||
.dashboard .event .bottomrow > span {
|
||||
flex: 1 1 0% !important;
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
text-align: center !important;
|
||||
padding: 8px 12px !important;
|
||||
font-size: 12.5px !important;
|
||||
font-weight: 600 !important;
|
||||
border-radius: 0 !important;
|
||||
margin: 0 !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* Linkes Feld ("0 Bestellungen") in edlem Slate-Dunkelblau statt grellem Royalblau */
|
||||
.dashboard .widget .bottomrow .orders,
|
||||
.dashboard .widget .bottomrow > div:first-child,
|
||||
.dashboard .widget .bottomrow > span:first-child,
|
||||
.dashboard .widget .bottomrow > a:first-child,
|
||||
.dashboard .event .bottomrow .orders,
|
||||
.dashboard .event .bottomrow > div:first-child,
|
||||
.dashboard .event .bottomrow > span:first-child,
|
||||
.dashboard .event .bottomrow > a:first-child {
|
||||
.dashboard .event .bottomrow > span:first-child {
|
||||
background-color: #1e293b !important;
|
||||
color: #f8fafc !important;
|
||||
}
|
||||
@@ -702,8 +553,8 @@ fieldset legend {
|
||||
.jumbotron {
|
||||
background-color: var(--fk-card-bg) !important;
|
||||
border: 1px solid var(--fk-border) !important;
|
||||
border-radius: 10px !important;
|
||||
box-shadow: 0 1px 4px rgba(15, 23, 42, 0.03) !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: 0 2px 8px rgba(15, 23, 42, 0.03) !important;
|
||||
}
|
||||
|
||||
.panel-default > .panel-heading,
|
||||
@@ -712,29 +563,19 @@ fieldset legend {
|
||||
color: var(--fk-text-main) !important;
|
||||
border-bottom: 1px solid var(--fk-border) !important;
|
||||
font-weight: 600 !important;
|
||||
padding: 13px 18px !important;
|
||||
border-top-left-radius: 10px !important;
|
||||
border-top-right-radius: 10px !important;
|
||||
padding: 14px 18px !important;
|
||||
border-top-left-radius: 12px !important;
|
||||
border-top-right-radius: 12px !important;
|
||||
}
|
||||
|
||||
/* --- BUTTONS, INPUT-GROUPS, UMSCHALTER ("Alle | aktiv") & BADGES --- */
|
||||
/* --- BUTTONS, UMSCHALTER ("Alle | aktiv") & BADGES --- */
|
||||
.btn {
|
||||
border-radius: 7px !important;
|
||||
border-radius: 8px !important;
|
||||
font-weight: 500 !important;
|
||||
transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease !important;
|
||||
transition: all 0.18s ease !important;
|
||||
}
|
||||
|
||||
.btn-xs,
|
||||
.btn-group-xs > .btn {
|
||||
border-radius: 5px !important;
|
||||
}
|
||||
|
||||
.btn-sm,
|
||||
.btn-group-sm > .btn {
|
||||
border-radius: 6px !important;
|
||||
}
|
||||
|
||||
/* Sekundäre Buttons ("Deaktivieren", "Gehe zu", Kopieren/QR) mit sanftem Rahmen */
|
||||
/* Sekundäre Buttons ("Deaktivieren", "Gehe zu") mit sanftem Rahmen statt Schwarz */
|
||||
.btn-default {
|
||||
background-color: #ffffff !important;
|
||||
border: 1px solid #cbd5e1 !important;
|
||||
@@ -757,21 +598,22 @@ fieldset legend {
|
||||
background: var(--fk-gradient-primary) !important;
|
||||
border-color: var(--fk-indigo) !important;
|
||||
color: #ffffff !important;
|
||||
box-shadow: 0 2px 6px rgba(79, 70, 229, 0.22) !important;
|
||||
box-shadow: 0 2px 8px rgba(79, 70, 229, 0.25) !important;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--fk-gradient-primary) !important;
|
||||
border: 1px solid transparent !important;
|
||||
border: none !important;
|
||||
color: #ffffff !important;
|
||||
font-weight: 600 !important;
|
||||
box-shadow: 0 2px 6px rgba(79, 70, 229, 0.22) !important;
|
||||
box-shadow: 0 2px 8px rgba(79, 70, 229, 0.25) !important;
|
||||
}
|
||||
|
||||
.btn-primary:hover,
|
||||
.btn-primary:focus {
|
||||
background: var(--fk-gradient-hover) !important;
|
||||
box-shadow: 0 4px 12px rgba(79, 70, 229, 0.32) !important;
|
||||
box-shadow: 0 4px 14px rgba(79, 70, 229, 0.38) !important;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* "aktiv"-Badge in Smaragdgrün */
|
||||
@@ -785,49 +627,24 @@ fieldset legend {
|
||||
}
|
||||
|
||||
.form-control {
|
||||
border-radius: 7px !important;
|
||||
border-radius: 8px !important;
|
||||
border: 1px solid #cbd5e1 !important;
|
||||
background-color: #ffffff !important;
|
||||
color: var(--fk-text-main) !important;
|
||||
}
|
||||
|
||||
/* Input-Groups & Button-Groups im Backend sauber bündig halten */
|
||||
.input-group .form-control:not(:first-child):not(:last-child),
|
||||
.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.input-group .form-control:first-child,
|
||||
.input-group-addon:first-child,
|
||||
.input-group-btn:first-child > .btn,
|
||||
.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
|
||||
border-top-right-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
|
||||
.input-group .form-control:last-child,
|
||||
.input-group-addon:last-child,
|
||||
.input-group-btn:last-child > .btn,
|
||||
.btn-group > .btn:last-child:not(:first-child),
|
||||
.btn-group > .dropdown-toggle:not(:first-child) {
|
||||
border-top-left-radius: 0 !important;
|
||||
border-bottom-left-radius: 0 !important;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
border-color: var(--fk-indigo) !important;
|
||||
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.14) !important;
|
||||
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.15) !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
4. LOGIN-SCREEN (EXAKT MITTIG ZENTRIERT & SYMMETRISCHES LOGO)
|
||||
Abgesichert über .falkenthal-auth-body bzw. body:not(:has(#wrapper)):has(img.logo)
|
||||
========================================================================== */
|
||||
|
||||
body.falkenthal-auth-body,
|
||||
body.login,
|
||||
body:not(:has(#wrapper)):has(img.logo) {
|
||||
body:has(img.logo),
|
||||
body.login {
|
||||
background-color: #060b16 !important;
|
||||
background-image:
|
||||
radial-gradient(circle at 50% 35%, rgba(37, 99, 235, 0.22) 0%, rgba(124, 58, 237, 0.10) 45%, transparent 75%),
|
||||
@@ -844,31 +661,28 @@ body:not(:has(#wrapper)):has(img.logo) {
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body > .container,
|
||||
body:not(:has(#wrapper)):has(img.logo) > .container {
|
||||
body:has(img.logo) > .container {
|
||||
width: 100% !important;
|
||||
max-width: 420px !important;
|
||||
margin: 0 auto !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body > .container .row,
|
||||
body:not(:has(#wrapper)):has(img.logo) > .container .row {
|
||||
body:has(img.logo) > .container .row {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body > .container [class*="col-"],
|
||||
body:not(:has(#wrapper)):has(img.logo) > .container [class*="col-"] {
|
||||
body:has(img.logo) > .container [class*="col-"] {
|
||||
width: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
float: none !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body .container img.logo,
|
||||
body:not(:has(#wrapper)):has(img.logo) .container img.logo,
|
||||
.container img.logo,
|
||||
.container-fluid img.logo,
|
||||
.form-signin img.logo {
|
||||
content: url('/static/whitelabel/login-logo.svg?v=1.8.5') !important;
|
||||
content: url('/static/whitelabel/login-logo.svg?v=7') !important;
|
||||
height: 115px !important;
|
||||
max-height: 115px !important;
|
||||
width: auto !important;
|
||||
@@ -877,12 +691,9 @@ body:not(:has(#wrapper)):has(img.logo) .container img.logo,
|
||||
filter: drop-shadow(0 0 18px rgba(0, 229, 255, 0.28)) !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body .panel,
|
||||
body.falkenthal-auth-body .well,
|
||||
body.falkenthal-auth-body .form-signin,
|
||||
body:not(:has(#wrapper)):has(img.logo) .panel,
|
||||
body:not(:has(#wrapper)):has(img.logo) .well,
|
||||
body:not(:has(#wrapper)):has(img.logo) .form-signin,
|
||||
body:has(img.logo) .panel,
|
||||
body:has(img.logo) .well,
|
||||
body:has(img.logo) .form-signin,
|
||||
.login-panel {
|
||||
background: rgba(15, 23, 42, 0.78) !important;
|
||||
backdrop-filter: blur(16px) !important;
|
||||
@@ -895,141 +706,24 @@ body:not(:has(#wrapper)):has(img.logo) .form-signin,
|
||||
margin-bottom: 18px !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body label,
|
||||
body.falkenthal-auth-body .control-label,
|
||||
body.falkenthal-auth-body .checkbox label,
|
||||
body:not(:has(#wrapper)):has(img.logo) label,
|
||||
body:not(:has(#wrapper)):has(img.logo) .control-label,
|
||||
body:not(:has(#wrapper)):has(img.logo) .checkbox label {
|
||||
body:has(img.logo) label,
|
||||
body:has(img.logo) .control-label,
|
||||
body:has(img.logo) .checkbox label {
|
||||
color: #cbd5e1 !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body .form-control,
|
||||
body:not(:has(#wrapper)):has(img.logo) .form-control {
|
||||
body:has(img.logo) .form-control {
|
||||
background-color: rgba(6, 11, 22, 0.78) !important;
|
||||
border: 1px solid rgba(148, 163, 184, 0.28) !important;
|
||||
color: #f8fafc !important;
|
||||
height: 42px !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body .form-control:focus,
|
||||
body:not(:has(#wrapper)):has(img.logo) .form-control:focus {
|
||||
body:has(img.logo) .form-control:focus {
|
||||
border-color: var(--fk-cyan) !important;
|
||||
box-shadow: 0 0 0 3px rgba(0, 229, 255, 0.18) !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body a,
|
||||
body:not(:has(#wrapper)):has(img.logo) a {
|
||||
body:has(img.logo) a {
|
||||
color: #60a5fa !important;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
5. MOBILE UX & RESPONSIVE ANPASSUNGEN (BACKEND)
|
||||
========================================================================== */
|
||||
|
||||
@media (max-width: 767px) {
|
||||
#page-wrapper {
|
||||
padding: 16px 14px !important;
|
||||
}
|
||||
|
||||
#page-wrapper h1 {
|
||||
font-size: 22px !important;
|
||||
margin-bottom: 14px !important;
|
||||
}
|
||||
|
||||
.navbar-header .navbar-brand,
|
||||
a.navbar-brand {
|
||||
width: 180px !important;
|
||||
background-size: auto 30px !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body .panel,
|
||||
body.falkenthal-auth-body .well,
|
||||
body.falkenthal-auth-body .form-signin,
|
||||
body:not(:has(#wrapper)):has(img.logo) .panel,
|
||||
body:not(:has(#wrapper)):has(img.logo) .well,
|
||||
body:not(:has(#wrapper)):has(img.logo) .form-signin {
|
||||
padding: 20px 18px !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
6. FOOTER & PLATTFORM-BAR (CONTROL & AUTH)
|
||||
========================================================================== */
|
||||
|
||||
footer {
|
||||
margin-top: 40px;
|
||||
padding: 20px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar {
|
||||
width: 100%;
|
||||
margin-top: 12px;
|
||||
padding-top: 14px;
|
||||
border-top: 1px solid var(--fk-border);
|
||||
font-size: 12px;
|
||||
color: var(--fk-text-muted);
|
||||
text-align: center;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar .falkenthal-platform-info {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 4px 0;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar .ft-brand {
|
||||
font-weight: 600;
|
||||
color: var(--fk-text-secondary);
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar a {
|
||||
color: var(--fk-text-muted) !important;
|
||||
text-decoration: none !important;
|
||||
font-weight: 500;
|
||||
transition: color 0.15s ease;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar a:hover {
|
||||
color: var(--fk-blue) !important;
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar .ft-sep {
|
||||
margin: 0 6px;
|
||||
color: #cbd5e1;
|
||||
}
|
||||
|
||||
/* Spezifische Footer-Anpassung für die Dark-Glassmorphism Loginseite */
|
||||
body.falkenthal-auth-body .falkenthal-platform-bar,
|
||||
body:not(:has(#wrapper)):has(img.logo) .falkenthal-platform-bar {
|
||||
border-top-color: rgba(99, 102, 241, 0.2) !important;
|
||||
color: #94a3b8 !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body .falkenthal-platform-bar .ft-brand,
|
||||
body:not(:has(#wrapper)):has(img.logo) .falkenthal-platform-bar .ft-brand {
|
||||
color: #cbd5e1 !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body .falkenthal-platform-bar a,
|
||||
body:not(:has(#wrapper)):has(img.logo) .falkenthal-platform-bar a {
|
||||
color: #94a3b8 !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body .falkenthal-platform-bar a:hover,
|
||||
body:not(:has(#wrapper)):has(img.logo) .falkenthal-platform-bar a:hover {
|
||||
color: var(--fk-cyan) !important;
|
||||
}
|
||||
|
||||
body.falkenthal-auth-body .falkenthal-platform-bar .ft-sep,
|
||||
body:not(:has(#wrapper)):has(img.logo) .falkenthal-platform-bar .ft-sep {
|
||||
color: #475569 !important;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* ==========================================================================
|
||||
FALKENTHAL MODERN SHOP UI/UX UPGRADE (presale.css - v1.8.5)
|
||||
Farb-, Geometrie- & Kontrastneutral: Respektiert 100 % der Veranstalter-Farben,
|
||||
Logos, Bootstrap-Input-Groups sowie helle UND dunkle Veranstalter-Hintergründe!
|
||||
FALKENTHAL MODERN SHOP UI/UX UPGRADE (presale.css)
|
||||
Farbneutral: Respektiert 100 % der Veranstalter-Farben, Logos & Hintergründe!
|
||||
========================================================================== */
|
||||
|
||||
body {
|
||||
@@ -10,194 +9,84 @@ body {
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 1. MODERNE CARDS & PANELS IM TICKETSHOP (Native Pretix-Rahmenfarben bleiben erhalten!) */
|
||||
/* 1. MODERNE CARDS & PANELS IM TICKETSHOP */
|
||||
.panel {
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 10px -2px rgba(0, 0, 0, 0.04);
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(15, 23, 42, 0.08);
|
||||
box-shadow: 0 4px 20px -2px rgba(15, 23, 42, 0.05);
|
||||
overflow: hidden;
|
||||
transition: box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.panel-heading {
|
||||
padding: 13px 18px;
|
||||
padding: 15px 20px;
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
/* 2. BUTTONS, EINGABEFELDER & MENGENAUSWAHL (ADAPTIVE RAHMEN FÜR LIGHT & DARK THEMES) */
|
||||
/* 2. PRODUKT- & TICKETZEILEN (MICRO-INTERACTIONS) */
|
||||
.product-row,
|
||||
.variation-row {
|
||||
border-radius: 8px;
|
||||
padding: 12px 10px;
|
||||
transition: background-color 0.18s ease;
|
||||
}
|
||||
|
||||
.product-row:hover {
|
||||
background-color: rgba(15, 23, 42, 0.025);
|
||||
}
|
||||
|
||||
/* 3. BUTTONS & EINGABEFELDER (MODERNE GEOMETRIE OHNE FARB-ZWANG) */
|
||||
.btn {
|
||||
border-radius: 6px;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
|
||||
padding: 9px 18px;
|
||||
transition: transform 0.15s ease, box-shadow 0.2s ease, background-color 0.18s ease;
|
||||
}
|
||||
|
||||
/* Sekundäre Buttons & Mengenauswahl-Buttons ([-][+]) behalten auf hellen UND dunklen
|
||||
Veranstalter-Hintergründen beim Hover immer einen klaren, sichtbaren Rahmen! */
|
||||
.btn-default {
|
||||
border: 1px solid rgba(128, 128, 128, 0.35);
|
||||
border-color: color-mix(in srgb, currentColor 25%, transparent);
|
||||
.btn:hover,
|
||||
.btn:focus {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(15, 23, 42, 0.12);
|
||||
}
|
||||
|
||||
.btn-default:hover,
|
||||
.btn-default:focus,
|
||||
.btn-default:active {
|
||||
border-color: rgba(128, 128, 128, 0.55) !important;
|
||||
border-color: color-mix(in srgb, currentColor 42%, transparent) !important;
|
||||
background-color: rgba(128, 128, 128, 0.08);
|
||||
background-color: color-mix(in srgb, currentColor 6%, transparent);
|
||||
}
|
||||
|
||||
/* Standalone-Eingabefelder (außerhalb von .input-group) dezent abrunden */
|
||||
.form-control:not(.input-group .form-control) {
|
||||
border-radius: 6px;
|
||||
.btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.form-control {
|
||||
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
||||
border-radius: 8px;
|
||||
height: 40px;
|
||||
border: 1px solid rgba(15, 23, 42, 0.18);
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.02);
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
/* Mengenauswahl ([-][ 0 ][+]) und andere Bootstrap .input-group Elemente
|
||||
exakt bündig auf einer Linie und mit durchgehend sichtbaren Rahmen halten */
|
||||
.input-group .form-control {
|
||||
border-radius: 0;
|
||||
.form-control:focus {
|
||||
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.15);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.input-group > .form-control:first-child,
|
||||
.input-group-btn:first-child > .btn,
|
||||
.input-group-btn:first-child > .btn-group > .btn,
|
||||
.input-group-addon:first-child {
|
||||
border-top-left-radius: 6px;
|
||||
border-bottom-left-radius: 6px;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.input-group > .form-control:last-child,
|
||||
.input-group-btn:last-child > .btn,
|
||||
.input-group-btn:last-child > .btn-group > .btn,
|
||||
.input-group-addon:last-child {
|
||||
border-top-right-radius: 6px;
|
||||
border-bottom-right-radius: 6px;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
/* 3. KALENDER & EVENT-KACHELN IN REIHEN */
|
||||
/* 4. KALENDER & EVENT-KACHELN IN REIHEN */
|
||||
.event-calendar td.has-events {
|
||||
border-radius: 6px;
|
||||
border-radius: 8px;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
|
||||
.subevent-list .subevent-row {
|
||||
border-radius: 8px;
|
||||
border-radius: 10px;
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 8px;
|
||||
transition: box-shadow 0.2s ease, transform 0.15s ease;
|
||||
}
|
||||
|
||||
/* 4. WARENKORB & HINWEISBOXEN (INKL. TESTMODUS-BANNER MIT LINKEM ICON-BALKEN) */
|
||||
/* 5. WARENKORB & CHECKOUT-FORTSCHRITT */
|
||||
.cart-row {
|
||||
padding: 12px 8px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
box-shadow: 0 2px 10px rgba(15, 23, 42, 0.05);
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
6. FOOTER & PLATTFORM-RECHTSTEXTE (ADAPTIV IN SHOP & WIDGET-IFRAME)
|
||||
========================================================================== */
|
||||
footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-top: 40px;
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
footer nav ul {
|
||||
margin-bottom: 0;
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
gap: 8px 16px;
|
||||
}
|
||||
|
||||
footer nav ul li a {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar {
|
||||
width: 100%;
|
||||
margin-top: 14px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid rgba(128, 128, 128, 0.2);
|
||||
border-top-color: color-mix(in srgb, currentColor 15%, transparent);
|
||||
font-size: 12px;
|
||||
color: inherit;
|
||||
opacity: 0.78;
|
||||
text-align: center;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar .falkenthal-platform-info {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 4px 0;
|
||||
max-width: 100%;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar .ft-brand {
|
||||
font-weight: 600;
|
||||
color: inherit;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar a {
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
font-weight: 500;
|
||||
opacity: 0.92;
|
||||
transition: opacity 0.15s ease, text-decoration 0.15s ease;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar a:hover,
|
||||
.falkenthal-platform-bar a:focus {
|
||||
opacity: 1;
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
.falkenthal-platform-bar .ft-sep {
|
||||
margin: 0 6px;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
/* Garantierte Sichtbarkeit der Plattform-Pflichtangaben im eingebetteten Pretix-Widget (Checkout-iFrame) */
|
||||
.is-iframe footer,
|
||||
body.iframe footer,
|
||||
body[data-iframe] footer {
|
||||
display: flex !important;
|
||||
visibility: visible !important;
|
||||
margin-top: 20px;
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
|
||||
.is-iframe .falkenthal-platform-bar,
|
||||
body.iframe .falkenthal-platform-bar,
|
||||
body[data-iframe] .falkenthal-platform-bar {
|
||||
display: block !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.falkenthal-platform-bar {
|
||||
font-size: 11px;
|
||||
}
|
||||
.falkenthal-platform-bar .ft-sep {
|
||||
margin: 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ with open("README.md", encoding="utf-8") as f:
|
||||
|
||||
setup(
|
||||
name="pretix-falkenthal-theme",
|
||||
version="1.8.5",
|
||||
version="1.7.3",
|
||||
description="Modern Slate & Blue-Violet White-Label Theme Plugin for pretix",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
|
||||
Reference in new issue
Block a user