Update020920251404

This commit is contained in:
Markus 2025-09-02 14:04:22 +02:00
parent 8119796efa
commit 6c64da0884
2 changed files with 181 additions and 97 deletions

View file

@ -30,8 +30,9 @@
.stack{display:grid;gap:16px} .stack{display:grid;gap:16px}
.stack-lg{display:grid;gap:24px} .stack-lg{display:grid;gap:24px}
.info-list{list-style:none;margin:0;padding:0;display:grid;gap:12px} .info-list{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.info-item{display:flex;gap:.75rem;align-items:flex-start} .info-item{display:flex;gap:.75rem;align-items:flex-start; justify-content:center; text-align:center}
.info-item .ico{flex:0 0 auto;line-height:0;color:#F5A623} .info-item .ico{flex:0 0 auto;line-height:0}
.info-item .txt a{ text-decoration:none;color:inherit; }
/* CTA-Buttons & Socials: nutzt eure bestehenden Klassen nur Layout-Hooks */ /* CTA-Buttons & Socials: nutzt eure bestehenden Klassen nur Layout-Hooks */
.cta__actions{display:flex;gap:.75rem;flex-wrap:wrap} .cta__actions{display:flex;gap:.75rem;flex-wrap:wrap}
@ -50,8 +51,8 @@
} }
textarea.form-control{min-height:160px;resize:vertical} textarea.form-control{min-height:160px;resize:vertical}
.form-control:focus{border-color:#F5A623;box-shadow:0 0 0 3px rgba(245,166,35,.18)} .form-control:focus{border-color:#F5A623;box-shadow:0 0 0 3px rgba(245,166,35,.18)}
.form-legal{margin:0;opacity:.9} /* p-Standardgröße bleibt erhalten */ .form-legal{margin:0;opacity:.9}
.card h3{margin:0 0 .5rem} /* nur Abstand, Typo kommt global von h3 */ .card h3{margin:0 0 .5rem}
</style> </style>
<section class="contact-wrap"> <section class="contact-wrap">
@ -63,30 +64,37 @@
<div class="card card-pad stack-lg"> <div class="card card-pad stack-lg">
<div class="stack"> <div class="stack">
<h3>Kontakt</h3> <h3>Kontakt</h3>
<ul class="info-list" style="display:grid;gap:12px;justify-items:center;text-align:center"> <ul class="info-list">
📍{{ with $addr }} {{ with $addr }}
<li class="info-item"> <li class="info-item">
<span class="ico" aria-hidden="true">📍</span>
<div class="txt">{{ . | markdownify }}</div> <div class="txt">{{ . | markdownify }}</div>
</li> </li>
{{ end }} {{ end }}
📧{{ with $email }}
{{ with $email }}
<li class="info-item"> <li class="info-item">
<span class="ico" aria-hidden="true">📧</span>
<div class="txt"> <div class="txt">
<a href="mailto:{{ . | safeURL }}" style="text-decoration:none;color:inherit;">{{ . }}</a> <a href="mailto:{{ . | safeURL }}">{{ . }}</a>
</div> </div>
</li> </li>
{{ end }} {{ end }}
📞{{ with $phone1 }}
{{ with $phone1 }}
<li class="info-item"> <li class="info-item">
<span class="ico" aria-hidden="true">📞</span>
<div class="txt"> <div class="txt">
<a href="tel:{{ . | safeURL }}" style="text-decoration:none;color:inherit;">{{ . }}</a> <a href="tel:{{ . | safeURL }}">{{ . }}</a>
</div> </div>
</li> </li>
{{ end }} {{ end }}
{{ with $phone2 }} {{ with $phone2 }}
<li class="info-item"> <li class="info-item">
<span class="ico" aria-hidden="true">📱</span>
<div class="txt"> <div class="txt">
<a href="tel:{{ . | safeURL }}" style="text-decoration:none;color:inherit;">{{ . }}</a> <a href="tel:{{ . | safeURL }}">{{ . }}</a>
</div> </div>
</li> </li>
{{ end }} {{ end }}
@ -112,7 +120,7 @@
<!-- ===== Formular ===== --> <!-- ===== Formular ===== -->
<div class="col-lg-7" data-reveal> <div class="col-lg-7" data-reveal>
<form method="POST" action="/send.php" class="card card-pad stack"> <form method="POST" action="/send.php" class="card card-pad stack" novalidate>
<div class="form-grid"> <div class="form-grid">
<div class="form-group"> <div class="form-group">
<label for="name" class="visually-hidden">Name</label> <label for="name" class="visually-hidden">Name</label>
@ -138,17 +146,25 @@
<label for="message" class="visually-hidden">Ihre Nachricht</label> <label for="message" class="visually-hidden">Ihre Nachricht</label>
<textarea id="message" name="message" class="form-control" rows="6" placeholder="Ihre Nachricht …" required></textarea> <textarea id="message" name="message" class="form-control" rows="6" placeholder="Ihre Nachricht …" required></textarea>
</div> </div>
<!-- hCaptcha -->
<!-- hCaptcha wird nach Consent via Tarteaucitron gerendert -->
<div class="form-group full"> <div class="form-group full">
<div class="h-captcha" data-sitekey="15a25108-bbc0-4d02-913c-4ada005ebd20" data-theme="dark"></div> <div class="h-captcha" data-sitekey="15a25108-bbc0-4d02-913c-4ada005ebd20" data-theme="dark"></div>
<noscript>
<div style="color:#b00020;font-size:13px;margin-top:6px;">
Hinweis: Bitte aktivieren Sie JavaScript, um das Captcha zu laden.
</div>
</noscript>
</div> </div>
</div> </div>
<p class="form-legal"> <p class="form-legal">
<label for="legal-consent"> <label for="legal-consent">
<input id="legal-consent" name="legal_consented" type="checkbox" required> <input id="legal-consent" name="legal_consented" type="checkbox" required>
Ich bin mit der Verarbeitung meiner Daten zum Zweck der Kontaktaufnahme einverstanden. (Datenschutzhinweise beachten) Ich bin mit der Verarbeitung meiner Daten zum Zweck der Kontaktaufnahme einverstanden. (Datenschutzhinweise beachten)
</label> </label>
</p> </p>
<div> <div>
<button class="cta__btn" type="submit" style="--btn-fs:1.5rem; --btn-py:14px; --btn-px:26px;"> <button class="cta__btn" type="submit" style="--btn-fs:1.5rem; --btn-py:14px; --btn-px:26px;">
<span aria-hidden="true"></span><span>Nachricht senden</span> <span aria-hidden="true"></span><span>Nachricht senden</span>
@ -156,15 +172,17 @@
</div> </div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
{{/* Reveal Init (falls global nicht vorhanden) */}} {{/* Reveal Init (falls global nicht vorhanden) */}}
<script> <script>
(function(){ (function(){
if (window.__contactRevealInit) return; window.__contactRevealInit = true; if (window.__contactRevealInit) return; window.__contactRevealInit = true;
var els = document.querySelectorAll("[data-reveal]"); var els = document.querySelectorAll("[data-reveal]");
if (!('IntersectionObserver' in window)){ els.forEach(e=>e.classList.add('is-visible')); return; } if (!('IntersectionObserver' in window)){ els.forEach(function(e){e.classList.add('is-visible')}); return; }
var io = new IntersectionObserver(function(entries){ var io = new IntersectionObserver(function(entries){
entries.forEach(function(entry){ entries.forEach(function(entry){
if(entry.isIntersecting){ if(entry.isIntersecting){
@ -173,9 +191,7 @@
} }
}); });
}, {threshold:.12}); }, {threshold:.12});
els.forEach(e=>io.observe(e)); els.forEach(function(e){io.observe(e)});
})(); })();
</script> </script>
<!-- hCaptcha-Skript -->
<script src="https://js.hcaptcha.com/1/api.js?hl=de"></script>
{{ end }} {{ end }}

View file

@ -1,24 +1,93 @@
<!-- JS Plugins + Main script --> <!-- JS Plugins + Main script -->
{{ $scripts := slice }} {{ $scripts := slice }}
{{ range site.Params.plugins.js}} {{ range site.Params.plugins.js}}
{{ if findRE "^http" .link }} {{ if findRE "^http" .link }}
<script src="{{ .link | relURL }}" type="application/javascript" {{.attributes | safeHTMLAttr}}></script> <script src="{{ .link | relURL }}" type="application/javascript" {{.attributes | safeHTMLAttr}}></script>
{{ else }} {{ else }}
{{ $scripts = $scripts | append (resources.Get .link) }} {{ $scripts = $scripts | append (resources.Get .link) }}
{{ end }} {{ end }}
{{ end }} {{ end }}
{{ $scripts := $scripts | append (resources.Get "js/script.js" | minify) }} {{ $scripts := $scripts | append (resources.Get "js/script.js" | minify) }}
{{ $scripts := $scripts | resources.Concat "js/script.js" | minify | fingerprint "sha512" }} {{ $scripts := $scripts | resources.Concat "js/script.js" | minify | fingerprint "sha512" }}
<script crossorigin="anonymous" defer="defer" integrity="{{ $scripts.Data.Integrity }}" type="application/javascript">{{$scripts.Content | safeJS}}</script> <script crossorigin="anonymous" defer="defer" integrity="{{ $scripts.Data.Integrity }}" type="application/javascript">{{$scripts.Content | safeJS}}</script>
<!-- Cookie-Manager -->
<script src="/tarteaucitron/tarteaucitron.js"></script> <script src="/tarteaucitron/tarteaucitron.js"></script>
<!-- hCaptcha Custom-Service (MUSS VOR init DEFINIERT SEIN) -->
<script>
(function() {
function renderAllHC() {
try {
var nodes = document.querySelectorAll('.h-captcha');
if (!nodes.length) return;
if (!window.hcaptcha || !window.hcaptcha.render) {
setTimeout(renderAllHC, 200);
return;
}
nodes.forEach(function(el) {
if (el.getAttribute('data-hc-rendered') === '1') return;
var sitekey = el.getAttribute('data-sitekey');
if (!sitekey) {
el.innerHTML = '<div style="color:#b00020;font-size:13px;padding:8px 0;">hCaptcha: data-sitekey fehlt.</div>';
return;
}
try {
window.hcaptcha.render(el, {
sitekey: sitekey,
theme: el.getAttribute('data-theme') || 'light',
size: el.getAttribute('data-size') || 'normal'
});
el.setAttribute('data-hc-rendered', '1');
} catch (e) {
el.innerHTML = '<div style="color:#b00020;font-size:13px;padding:8px 0;">hCaptcha Render-Fehler: ' + (e && e.message ? e.message : e) + '</div>';
}
});
} catch(e) {}
}
// globaler Callback für die API
window.__hcRenderAll = renderAllHC;
// hCaptcha als Tarteaucitron-Service
tarteaucitron.services.hcaptcha = {
key: 'hcaptcha',
type: 'other',
name: 'hCaptcha',
needConsent: true,
cookies: [],
uri: 'https://www.hcaptcha.com/privacy',
js: function () {
if (!document.getElementById('hcaptcha-api')) {
var s = document.createElement('script');
s.id = 'hcaptcha-api';
s.src = 'https://hcaptcha.com/1/api.js?render=explicit&onload=__hcRenderAll';
s.async = true;
s.defer = true;
s.onerror = function() {
document.querySelectorAll('.h-captcha').forEach(function(el){
el.innerHTML = '<div style="color:#b00020;font-size:13px;padding:8px 0;">hCaptcha API geblockt (CSP/Blocker?).</div>';
});
};
document.head.appendChild(s);
} else {
__hcRenderAll();
}
},
fallback: function () {
tarteaucitron.fallback(['h-captcha'], tarteaucitron.engage('hcaptcha'));
}
};
})();
</script>
<!-- Tarteaucitron initialisieren -->
<script type="text/javascript"> <script type="text/javascript">
tarteaucitron.init({ tarteaucitron.init({
"privacyUrl": "/datenschutz", "privacyUrl": "/datenschutz",
"bodyPosition": "top", "bodyPosition": "top",
"hashtag": "#tarteaucitron", "hashtag": "#tarteaucitron",
@ -27,7 +96,7 @@
"groupServices": true, "groupServices": true,
"showDetailsOnClick": false, "showDetailsOnClick": false,
"serviceDefaultState": "wait", // ← wichtig: wartet auf Nutzeraktion "serviceDefaultState": "wait",
"showAlertSmall": false, "showAlertSmall": false,
"cookieslist": false, "cookieslist": false,
@ -38,7 +107,7 @@
"adblocker": false, "adblocker": false,
"DenyAllCta": false, "DenyAllCta": false,
"AcceptAllCta": true, "AcceptAllCta": true,
"highPrivacy": true, // ← wichtig: kein Auto-Consent "highPrivacy": true,
"alwaysNeedConsent": false, "alwaysNeedConsent": false,
"handleBrowserDNTRequest": false, "handleBrowserDNTRequest": false,
@ -47,7 +116,7 @@
"useExternalCss": false, "useExternalCss": false,
"useExternalJs": false, "useExternalJs": false,
"mandatory": false, // ← notwendig, wenn man keine Pflicht-Cookies nutzt "mandatory": false,
"mandatoryCta": false, "mandatoryCta": false,
"googleConsentMode": true, "googleConsentMode": true,
@ -57,17 +126,16 @@
"dataLayer": false, "dataLayer": false,
"serverSide": false, "serverSide": false,
"partnersList": true "partnersList": true
}); });
</script> </script>
<!-- Matomo + hCaptcha in die Queue (NACH init) -->
<script> <script>
tarteaucitron.user.matomoId = 2; tarteaucitron.user.matomoId = 2;
tarteaucitron.user.matomoHost = 'https://matomo.amperion.at/';
tarteaucitron.user.matomoDontTrackPageView = false; // bei Bedarf true
tarteaucitron.user.matomoFullTracking = true; // bei Bedarf false
(tarteaucitron.job = tarteaucitron.job || []).push('matomocloud'); (tarteaucitron.job = tarteaucitron.job || []).push('matomocloud');
(tarteaucitron.job = tarteaucitron.job || []).push('hcaptcha');
</script> </script>
<script>tarteaucitron.user.matomoHost = 'https://matomo.amperion.at/';
tarteaucitron.user.matomoDontTrackPageView = dontTrackPageView (false | true);
tarteaucitron.user.matomoFullTracking = fullTracking (true | false);
</script>
<script type="text/javascript" src="/js/tarteaucitron.js"></script>