Compare commits

..
4 Commits
7 changed files with 299 additions and 766 deletions

No files matched your search

+6 -7
View File
@@ -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
View File
@@ -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">&middot;</span>'
f'<a href="{PLATFORM_IMPRINT_URL}" target="_blank" rel="noopener">Plattform-Impressum</a>'
'<span class="ft-sep">&middot;</span>'
f'<a href="{PLATFORM_PRIVACY_URL}" target="_blank" rel="noopener">Plattform-Datenschutz</a>'
'<span class="ft-sep">&middot;</span>'
f'<a href="{THEME_REPO_URL}" target="_blank" rel="noopener">Theme &amp; Quellcode (AGPLv3)</a>'
'</div>'
'</div>'
'</footer>'
footer_Html = (
f' &middot; <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>'
' &middot; '
f'<a href="{PLATFORM_IMPRINT_URL}" target="_blank" rel="noopener" style="color:#64748b;text-decoration:underline;">Plattform-Impressum</a>'
' &middot; '
f'<a href="{PLATFORM_PRIVACY_URL}" target="_blank" rel="noopener" style="color:#64748b;text-decoration:underline;">Plattform-Datenschutz</a>'
' &middot; '
f'<a href="{THEME_REPO_URL}" target="_blank" rel="noopener" style="color:#64748b;text-decoration:underline;">Theme &amp; 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>' +
' &middot; <a href="https://tickets.falkenthal.me/impressum" target="_blank" rel="noopener" style="color:inherit;text-decoration:underline;">Plattform-Impressum</a>' +
' &middot; <a href="https://tickets.falkenthal.me/datenschutz" target="_blank" rel="noopener" style="color:inherit;text-decoration:underline;">Plattform-Datenschutz</a>' +
' &middot; <a href="https://git.falkenthal.me/falkenthal/pretix-falkenthal-theme" target="_blank" rel="noopener" style="color:inherit;text-decoration:underline;">Theme &amp; 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).")
+1 -1
View File
@@ -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
View File
@@ -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>
"""
+78 -384
View File
@@ -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;
}
+50 -161
View File
@@ -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;
}
}
+1 -1
View File
@@ -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",