Checkout-Zahlungsarten: Karten klappen sofort beim Anklicken auf; HasiDog-Box zeigt Charaktertext & ist breiter

- Zahlungsart-Auswahl umgebaut: jede Karte (PayPal/Klarna/Kreditkarte/
  Banküberweisung) klappt den passenden "Verbinden"-Bereich jetzt SOFORT
  in sich selbst auf, sobald man draufklickt — kein Zwischenschritt, kein
  separates Panel weiter unten mehr. Rein CSS-gesteuert (:has()), reagiert
  augenblicklich auf den Klick.
- Unterkategorie-Vorstellungsbox (z.B. HasiDog) zeigt jetzt wieder den
  persönlichen Charaktertext ("Ich bin klein, knuffig, wuschelig...")
  statt der Produktbeschreibung, plus den Cliffhanger-Satz "Wenn du mehr
  über mich erfahren möchtest, dann klicke" vor dem Button — für alle 6
  Tier-Serien (Kuh, Hase, Wal, Oktopus, Schildkröte, Pinguin). Foto und
  Überschrift sind jetzt anklickbar und führen zur echten Produktseite,
  damit trotz des reinen Charaktertexts nichts an Kaufbarkeit verloren
  geht. Textspalte gegenüber Fotospalte verbreitert.

Verifiziert per Puppeteer gegen den echten Build: PayPal-Karte zeigt beim
Laden sofort den echten SDK-Button, Kreditkarte/Banküberweisung klappen
unmittelbar beim Klick auf (ohne Wartezeit geprüft), Bankdaten und
Charaktertext korrekt, keine Konsolenfehler.
This commit is contained in:
qcigano
2026-08-02 19:44:39 +02:00
parent aa53a6321d
commit 87032eeba8
9 changed files with 268 additions and 276 deletions
+52 -56
View File
@@ -22,56 +22,61 @@ const t = useTranslations(lang);
<div class="checkout-split-col">
<h3>{t.checkout.step2}</h3>
<div class="payment-options">
<label class="pay-option" style="--brand-color:#009cde; --brand-bg:#003087;">
<span class="pay-icon" style="background:linear-gradient(160deg, #0070ba, #003087); color:#fff;">P</span>
<span>PayPal</span>
<input type="radio" name="pay" value="paypal" checked />
</label>
<label class="pay-option" style="--brand-color:#ffb3c7; --brand-bg:#17120f;">
<span class="pay-icon" style="background:linear-gradient(160deg, #ffc9d8, #ffb3c7); color:#0a0a0a;">K</span>
<span>Klarna</span>
<input type="radio" name="pay" value="klarna" />
</label>
<label class="pay-option" style="--brand-color:#ff9838; --brand-bg:#241f3d;">
<span class="pay-icon pay-icon-cc" style="background:linear-gradient(160deg, #2a2a3d, #14141f);">
<span class="cc-dot cc-dot-a"></span><span class="cc-dot cc-dot-b"></span>
</span>
<span>{t.checkout.creditCard}<span class="pay-sub">{t.checkout.creditCardSub}</span></span>
<input type="radio" name="pay" value="kreditkarte" />
</label>
<label class="pay-option" style="--brand-color:#7fa8c9; --brand-bg:#3b5a76;">
<span class="pay-icon pay-icon-emoji" style="background:linear-gradient(160deg, #4d7599, #2c4258);">🏦</span>
<span>{t.checkout.bankTransfer}</span>
<input type="radio" name="pay" value="ueberweisung" />
</label>
</div>
<div class="pay-connect">
<div class="pay-panel" data-panel="paypal">
<p>{t.checkout.payPalHint}</p>
<div id="paypal-button-container"></div>
<div class="pay-card" style="--brand-color:#009cde; --brand-bg:#003087;">
<label class="pay-option">
<span class="pay-icon" style="background:linear-gradient(160deg, #0070ba, #003087); color:#fff;">P</span>
<span>PayPal</span>
<input type="radio" name="pay" value="paypal" checked />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.payPalHint}</p>
<div id="paypal-button-container"></div>
</div>
</div>
<div class="pay-panel" data-panel="klarna" hidden>
<p>{t.checkout.klarnaHint}</p>
<button type="button" class="btn btn-outline pay-connect-btn" id="klarna-connect">{t.checkout.klarnaConnect}</button>
<p class="pay-connect-status" id="klarna-status"></p>
<div class="pay-card" style="--brand-color:#ffb3c7; --brand-bg:#17120f;">
<label class="pay-option">
<span class="pay-icon" style="background:linear-gradient(160deg, #ffc9d8, #ffb3c7); color:#0a0a0a;">K</span>
<span>Klarna</span>
<input type="radio" name="pay" value="klarna" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.klarnaHint}</p>
<button type="button" class="btn btn-outline pay-connect-btn" id="klarna-connect">{t.checkout.klarnaConnect}</button>
<p class="pay-connect-status" id="klarna-status"></p>
</div>
</div>
<div class="pay-panel" data-panel="kreditkarte" hidden>
<p>{t.checkout.cardHint}</p>
<div class="card-fields">
<div>
<label for="cc-number">{t.checkout.cardNumber}</label>
<input type="text" id="cc-number" inputmode="numeric" placeholder="1234 5678 9012 3456" maxlength="19" />
</div>
<div class="grid grid-2">
<div><label for="cc-expiry">{t.checkout.cardExpiry}</label><input type="text" id="cc-expiry" placeholder="MM/YY" maxlength="5" /></div>
<div><label for="cc-cvc">{t.checkout.cardCvc}</label><input type="text" id="cc-cvc" inputmode="numeric" placeholder="123" maxlength="4" /></div>
<div class="pay-card" style="--brand-color:#ff9838; --brand-bg:#241f3d;">
<label class="pay-option">
<span class="pay-icon pay-icon-cc" style="background:linear-gradient(160deg, #2a2a3d, #14141f);">
<span class="cc-dot cc-dot-a"></span><span class="cc-dot cc-dot-b"></span>
</span>
<span>{t.checkout.creditCard}<span class="pay-sub">{t.checkout.creditCardSub}</span></span>
<input type="radio" name="pay" value="kreditkarte" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.cardHint}</p>
<div class="card-fields">
<div>
<label for="cc-number">{t.checkout.cardNumber}</label>
<input type="text" id="cc-number" inputmode="numeric" placeholder="1234 5678 9012 3456" maxlength="19" />
</div>
<div class="grid grid-2">
<div><label for="cc-expiry">{t.checkout.cardExpiry}</label><input type="text" id="cc-expiry" placeholder="MM/YY" maxlength="5" /></div>
<div><label for="cc-cvc">{t.checkout.cardCvc}</label><input type="text" id="cc-cvc" inputmode="numeric" placeholder="123" maxlength="4" /></div>
</div>
</div>
</div>
</div>
<div class="pay-panel" data-panel="ueberweisung" hidden>
<p>{t.checkout.bankHintReal}</p>
<div class="bank-details" id="bank-details"></div>
<div class="pay-card" style="--brand-color:#7fa8c9; --brand-bg:#3b5a76;">
<label class="pay-option">
<span class="pay-icon pay-icon-emoji" style="background:linear-gradient(160deg, #4d7599, #2c4258);">🏦</span>
<span>{t.checkout.bankTransfer}</span>
<input type="radio" name="pay" value="ueberweisung" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.bankHintReal}</p>
<div class="bank-details" id="bank-details"></div>
</div>
</div>
</div>
@@ -191,17 +196,8 @@ import { bankverbindung, bankverbindungVollstaendig } from "../../../data/bankve
renderSummary();
landSelect.addEventListener("change", renderSummary);
// Zahlungsart-Auswahl: pro Methode ein Panel, nur die gewählte ist sichtbar. Macht die
// Auswahl sofort "aktionabel" statt ein reines Formularfeld zu sein.
const payPanels = document.querySelectorAll(".pay-panel");
function showPayPanel(method) {
payPanels.forEach((p) => { p.hidden = p.dataset.panel !== method; });
}
document.querySelectorAll('input[name="pay"]').forEach((radio) => {
radio.addEventListener("change", () => showPayPanel(radio.value));
});
const initialPay = document.querySelector('input[name="pay"]:checked');
if (initialPay) showPayPanel(initialPay.value);
// Zahlungsart-Auswahl: der "Verbinden"-Bereich jeder Karte klappt rein über CSS
// (:has(input:checked)) sofort auf, sobald man die Karte anklickt — kein JS, keine Verzögerung.
// PayPal: echte PayPal Smart Buttons über das offizielle JS-SDK (Sandbox-Client-ID "sb" —
// kostenlos, ohne eigenes Konto testbar). Klick öffnet den echten PayPal-Login-Popup. Für den
@@ -38,20 +38,20 @@ const weitere = echtProdukte.slice(1);
{featured ? (
<section class="section-tight">
<div class="container grid grid-2 intro">
<div class="portrait-frame portrait">
<a class="portrait-frame portrait" href={`/ch/produkt/${featured.slug}/`} aria-label={featured.name[lang]}>
{featured.bilder && featured.bilder.length > 0 ? (
<img class="product-photo" src={featured.bilder[0]} alt={featured.name[lang]} loading="lazy" />
) : (
<div class="img-placeholder" role="img" aria-label={featured.name[lang]}></div>
)}
</div>
</a>
<div>
{sub.vorstellung && <span class="eyebrow">{sub.vorstellung[lang].split("\n")[0]}</span>}
<h2>{featured.name[lang]}</h2>
<p class="lead">{featured.beschreibung[lang]}</p>
<h2><a href={`/ch/produkt/${featured.slug}/`}>{featured.name[lang]}</a></h2>
<p class="lead">{sub.vorstellung ? sub.vorstellung[lang].split("\n")[1] : featured.beschreibung[lang]}</p>
{sub.mehrLink && (
<div class="character-more">
<p>Wosch meh über {sub.name[lang]} wüsse?</p>
<p>Wenn du meh über mich wüsse witt, de klick</p>
<a class="btn btn-outline" href={sub.mehrLink} target="_blank" rel="noopener">da →</a>
</div>
)}
@@ -66,7 +66,7 @@ const weitere = echtProdukte.slice(1);
{sub.vorstellung[lang].split("\n").map((line) => <p>{line}</p>)}
{sub.mehrLink && (
<div class="character-more">
<p>Wosch meh über {sub.name[lang]} wüsse?</p>
<p>Wenn du meh über mich wüsse witt, de klick</p>
<a class="btn btn-outline" href={sub.mehrLink} target="_blank" rel="noopener">da →</a>
</div>
)}
+52 -56
View File
@@ -22,56 +22,61 @@ const t = useTranslations(lang);
<div class="checkout-split-col">
<h3>{t.checkout.step2}</h3>
<div class="payment-options">
<label class="pay-option" style="--brand-color:#009cde; --brand-bg:#003087;">
<span class="pay-icon" style="background:linear-gradient(160deg, #0070ba, #003087); color:#fff;">P</span>
<span>PayPal</span>
<input type="radio" name="pay" value="paypal" checked />
</label>
<label class="pay-option" style="--brand-color:#ffb3c7; --brand-bg:#17120f;">
<span class="pay-icon" style="background:linear-gradient(160deg, #ffc9d8, #ffb3c7); color:#0a0a0a;">K</span>
<span>Klarna</span>
<input type="radio" name="pay" value="klarna" />
</label>
<label class="pay-option" style="--brand-color:#ff9838; --brand-bg:#241f3d;">
<span class="pay-icon pay-icon-cc" style="background:linear-gradient(160deg, #2a2a3d, #14141f);">
<span class="cc-dot cc-dot-a"></span><span class="cc-dot cc-dot-b"></span>
</span>
<span>{t.checkout.creditCard}<span class="pay-sub">{t.checkout.creditCardSub}</span></span>
<input type="radio" name="pay" value="kreditkarte" />
</label>
<label class="pay-option" style="--brand-color:#7fa8c9; --brand-bg:#3b5a76;">
<span class="pay-icon pay-icon-emoji" style="background:linear-gradient(160deg, #4d7599, #2c4258);">🏦</span>
<span>{t.checkout.bankTransfer}</span>
<input type="radio" name="pay" value="ueberweisung" />
</label>
</div>
<div class="pay-connect">
<div class="pay-panel" data-panel="paypal">
<p>{t.checkout.payPalHint}</p>
<div id="paypal-button-container"></div>
<div class="pay-card" style="--brand-color:#009cde; --brand-bg:#003087;">
<label class="pay-option">
<span class="pay-icon" style="background:linear-gradient(160deg, #0070ba, #003087); color:#fff;">P</span>
<span>PayPal</span>
<input type="radio" name="pay" value="paypal" checked />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.payPalHint}</p>
<div id="paypal-button-container"></div>
</div>
</div>
<div class="pay-panel" data-panel="klarna" hidden>
<p>{t.checkout.klarnaHint}</p>
<button type="button" class="btn btn-outline pay-connect-btn" id="klarna-connect">{t.checkout.klarnaConnect}</button>
<p class="pay-connect-status" id="klarna-status"></p>
<div class="pay-card" style="--brand-color:#ffb3c7; --brand-bg:#17120f;">
<label class="pay-option">
<span class="pay-icon" style="background:linear-gradient(160deg, #ffc9d8, #ffb3c7); color:#0a0a0a;">K</span>
<span>Klarna</span>
<input type="radio" name="pay" value="klarna" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.klarnaHint}</p>
<button type="button" class="btn btn-outline pay-connect-btn" id="klarna-connect">{t.checkout.klarnaConnect}</button>
<p class="pay-connect-status" id="klarna-status"></p>
</div>
</div>
<div class="pay-panel" data-panel="kreditkarte" hidden>
<p>{t.checkout.cardHint}</p>
<div class="card-fields">
<div>
<label for="cc-number">{t.checkout.cardNumber}</label>
<input type="text" id="cc-number" inputmode="numeric" placeholder="1234 5678 9012 3456" maxlength="19" />
</div>
<div class="grid grid-2">
<div><label for="cc-expiry">{t.checkout.cardExpiry}</label><input type="text" id="cc-expiry" placeholder="MM/YY" maxlength="5" /></div>
<div><label for="cc-cvc">{t.checkout.cardCvc}</label><input type="text" id="cc-cvc" inputmode="numeric" placeholder="123" maxlength="4" /></div>
<div class="pay-card" style="--brand-color:#ff9838; --brand-bg:#241f3d;">
<label class="pay-option">
<span class="pay-icon pay-icon-cc" style="background:linear-gradient(160deg, #2a2a3d, #14141f);">
<span class="cc-dot cc-dot-a"></span><span class="cc-dot cc-dot-b"></span>
</span>
<span>{t.checkout.creditCard}<span class="pay-sub">{t.checkout.creditCardSub}</span></span>
<input type="radio" name="pay" value="kreditkarte" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.cardHint}</p>
<div class="card-fields">
<div>
<label for="cc-number">{t.checkout.cardNumber}</label>
<input type="text" id="cc-number" inputmode="numeric" placeholder="1234 5678 9012 3456" maxlength="19" />
</div>
<div class="grid grid-2">
<div><label for="cc-expiry">{t.checkout.cardExpiry}</label><input type="text" id="cc-expiry" placeholder="MM/YY" maxlength="5" /></div>
<div><label for="cc-cvc">{t.checkout.cardCvc}</label><input type="text" id="cc-cvc" inputmode="numeric" placeholder="123" maxlength="4" /></div>
</div>
</div>
</div>
</div>
<div class="pay-panel" data-panel="ueberweisung" hidden>
<p>{t.checkout.bankHintReal}</p>
<div class="bank-details" id="bank-details"></div>
<div class="pay-card" style="--brand-color:#7fa8c9; --brand-bg:#3b5a76;">
<label class="pay-option">
<span class="pay-icon pay-icon-emoji" style="background:linear-gradient(160deg, #4d7599, #2c4258);">🏦</span>
<span>{t.checkout.bankTransfer}</span>
<input type="radio" name="pay" value="ueberweisung" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.bankHintReal}</p>
<div class="bank-details" id="bank-details"></div>
</div>
</div>
</div>
@@ -194,17 +199,8 @@ import { bankverbindung, bankverbindungVollstaendig } from "../../data/bankverbi
renderSummary();
landSelect.addEventListener("change", renderSummary);
// Zahlungsart-Auswahl: pro Methode ein Panel, nur die gewählte ist sichtbar. Macht die
// Auswahl sofort "aktionabel" statt ein reines Formularfeld zu sein.
const payPanels = document.querySelectorAll(".pay-panel");
function showPayPanel(method) {
payPanels.forEach((p) => { p.hidden = p.dataset.panel !== method; });
}
document.querySelectorAll('input[name="pay"]').forEach((radio) => {
radio.addEventListener("change", () => showPayPanel(radio.value));
});
const initialPay = document.querySelector('input[name="pay"]:checked');
if (initialPay) showPayPanel(initialPay.value);
// Zahlungsart-Auswahl: der "Verbinden"-Bereich jeder Karte klappt rein über CSS
// (:has(input:checked)) sofort auf, sobald man die Karte anklickt — kein JS, keine Verzögerung.
// PayPal: echte PayPal Smart Buttons über das offizielle JS-SDK (Sandbox-Client-ID "sb" —
// kostenlos, ohne eigenes Konto testbar). Klick öffnet den echten PayPal-Login-Popup. Für den
+52 -56
View File
@@ -22,56 +22,61 @@ const t = useTranslations(lang);
<div class="checkout-split-col">
<h3>{t.checkout.step2}</h3>
<div class="payment-options">
<label class="pay-option" style="--brand-color:#009cde; --brand-bg:#003087;">
<span class="pay-icon" style="background:linear-gradient(160deg, #0070ba, #003087); color:#fff;">P</span>
<span>PayPal</span>
<input type="radio" name="pay" value="paypal" checked />
</label>
<label class="pay-option" style="--brand-color:#ffb3c7; --brand-bg:#17120f;">
<span class="pay-icon" style="background:linear-gradient(160deg, #ffc9d8, #ffb3c7); color:#0a0a0a;">K</span>
<span>Klarna</span>
<input type="radio" name="pay" value="klarna" />
</label>
<label class="pay-option" style="--brand-color:#ff9838; --brand-bg:#241f3d;">
<span class="pay-icon pay-icon-cc" style="background:linear-gradient(160deg, #2a2a3d, #14141f);">
<span class="cc-dot cc-dot-a"></span><span class="cc-dot cc-dot-b"></span>
</span>
<span>{t.checkout.creditCard}<span class="pay-sub">{t.checkout.creditCardSub}</span></span>
<input type="radio" name="pay" value="kreditkarte" />
</label>
<label class="pay-option" style="--brand-color:#7fa8c9; --brand-bg:#3b5a76;">
<span class="pay-icon pay-icon-emoji" style="background:linear-gradient(160deg, #4d7599, #2c4258);">🏦</span>
<span>{t.checkout.bankTransfer}</span>
<input type="radio" name="pay" value="ueberweisung" />
</label>
</div>
<div class="pay-connect">
<div class="pay-panel" data-panel="paypal">
<p>{t.checkout.payPalHint}</p>
<div id="paypal-button-container"></div>
<div class="pay-card" style="--brand-color:#009cde; --brand-bg:#003087;">
<label class="pay-option">
<span class="pay-icon" style="background:linear-gradient(160deg, #0070ba, #003087); color:#fff;">P</span>
<span>PayPal</span>
<input type="radio" name="pay" value="paypal" checked />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.payPalHint}</p>
<div id="paypal-button-container"></div>
</div>
</div>
<div class="pay-panel" data-panel="klarna" hidden>
<p>{t.checkout.klarnaHint}</p>
<button type="button" class="btn btn-outline pay-connect-btn" id="klarna-connect">{t.checkout.klarnaConnect}</button>
<p class="pay-connect-status" id="klarna-status"></p>
<div class="pay-card" style="--brand-color:#ffb3c7; --brand-bg:#17120f;">
<label class="pay-option">
<span class="pay-icon" style="background:linear-gradient(160deg, #ffc9d8, #ffb3c7); color:#0a0a0a;">K</span>
<span>Klarna</span>
<input type="radio" name="pay" value="klarna" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.klarnaHint}</p>
<button type="button" class="btn btn-outline pay-connect-btn" id="klarna-connect">{t.checkout.klarnaConnect}</button>
<p class="pay-connect-status" id="klarna-status"></p>
</div>
</div>
<div class="pay-panel" data-panel="kreditkarte" hidden>
<p>{t.checkout.cardHint}</p>
<div class="card-fields">
<div>
<label for="cc-number">{t.checkout.cardNumber}</label>
<input type="text" id="cc-number" inputmode="numeric" placeholder="1234 5678 9012 3456" maxlength="19" />
</div>
<div class="grid grid-2">
<div><label for="cc-expiry">{t.checkout.cardExpiry}</label><input type="text" id="cc-expiry" placeholder="MM/YY" maxlength="5" /></div>
<div><label for="cc-cvc">{t.checkout.cardCvc}</label><input type="text" id="cc-cvc" inputmode="numeric" placeholder="123" maxlength="4" /></div>
<div class="pay-card" style="--brand-color:#ff9838; --brand-bg:#241f3d;">
<label class="pay-option">
<span class="pay-icon pay-icon-cc" style="background:linear-gradient(160deg, #2a2a3d, #14141f);">
<span class="cc-dot cc-dot-a"></span><span class="cc-dot cc-dot-b"></span>
</span>
<span>{t.checkout.creditCard}<span class="pay-sub">{t.checkout.creditCardSub}</span></span>
<input type="radio" name="pay" value="kreditkarte" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.cardHint}</p>
<div class="card-fields">
<div>
<label for="cc-number">{t.checkout.cardNumber}</label>
<input type="text" id="cc-number" inputmode="numeric" placeholder="1234 5678 9012 3456" maxlength="19" />
</div>
<div class="grid grid-2">
<div><label for="cc-expiry">{t.checkout.cardExpiry}</label><input type="text" id="cc-expiry" placeholder="MM/YY" maxlength="5" /></div>
<div><label for="cc-cvc">{t.checkout.cardCvc}</label><input type="text" id="cc-cvc" inputmode="numeric" placeholder="123" maxlength="4" /></div>
</div>
</div>
</div>
</div>
<div class="pay-panel" data-panel="ueberweisung" hidden>
<p>{t.checkout.bankHintReal}</p>
<div class="bank-details" id="bank-details"></div>
<div class="pay-card" style="--brand-color:#7fa8c9; --brand-bg:#3b5a76;">
<label class="pay-option">
<span class="pay-icon pay-icon-emoji" style="background:linear-gradient(160deg, #4d7599, #2c4258);">🏦</span>
<span>{t.checkout.bankTransfer}</span>
<input type="radio" name="pay" value="ueberweisung" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.bankHintReal}</p>
<div class="bank-details" id="bank-details"></div>
</div>
</div>
</div>
@@ -191,17 +196,8 @@ import { bankverbindung, bankverbindungVollstaendig } from "../../../data/bankve
renderSummary();
landSelect.addEventListener("change", renderSummary);
// Zahlungsart-Auswahl: pro Methode ein Panel, nur die gewählte ist sichtbar. Macht die
// Auswahl sofort "aktionabel" statt ein reines Formularfeld zu sein.
const payPanels = document.querySelectorAll(".pay-panel");
function showPayPanel(method) {
payPanels.forEach((p) => { p.hidden = p.dataset.panel !== method; });
}
document.querySelectorAll('input[name="pay"]').forEach((radio) => {
radio.addEventListener("change", () => showPayPanel(radio.value));
});
const initialPay = document.querySelector('input[name="pay"]:checked');
if (initialPay) showPayPanel(initialPay.value);
// Zahlungsart-Auswahl: der "Verbinden"-Bereich jeder Karte klappt rein über CSS
// (:has(input:checked)) sofort auf, sobald man die Karte anklickt — kein JS, keine Verzögerung.
// PayPal: echte PayPal Smart Buttons über das offizielle JS-SDK (Sandbox-Client-ID "sb" —
// kostenlos, ohne eigenes Konto testbar). Klick öffnet den echten PayPal-Login-Popup. Für den
@@ -38,20 +38,20 @@ const weitere = echtProdukte.slice(1);
{featured ? (
<section class="section-tight">
<div class="container grid grid-2 intro">
<div class="portrait-frame portrait">
<a class="portrait-frame portrait" href={`/en/produkt/${featured.slug}/`} aria-label={featured.name[lang]}>
{featured.bilder && featured.bilder.length > 0 ? (
<img class="product-photo" src={featured.bilder[0]} alt={featured.name[lang]} loading="lazy" />
) : (
<div class="img-placeholder" role="img" aria-label={featured.name[lang]}></div>
)}
</div>
</a>
<div>
{sub.vorstellung && <span class="eyebrow">{sub.vorstellung[lang].split("\n")[0]}</span>}
<h2>{featured.name[lang]}</h2>
<p class="lead">{featured.beschreibung[lang]}</p>
<h2><a href={`/en/produkt/${featured.slug}/`}>{featured.name[lang]}</a></h2>
<p class="lead">{sub.vorstellung ? sub.vorstellung[lang].split("\n")[1] : featured.beschreibung[lang]}</p>
{sub.mehrLink && (
<div class="character-more">
<p>Want to learn more about {sub.name[lang]}?</p>
<p>If you'd like to learn more about me, just click</p>
<a class="btn btn-outline" href={sub.mehrLink} target="_blank" rel="noopener">here →</a>
</div>
)}
@@ -66,7 +66,7 @@ const weitere = echtProdukte.slice(1);
{sub.vorstellung[lang].split("\n").map((line) => <p>{line}</p>)}
{sub.mehrLink && (
<div class="character-more">
<p>Want to learn more about {sub.name[lang]}?</p>
<p>If you'd like to learn more about me, just click</p>
<a class="btn btn-outline" href={sub.mehrLink} target="_blank" rel="noopener">here →</a>
</div>
)}
+52 -56
View File
@@ -22,56 +22,61 @@ const t = useTranslations(lang);
<div class="checkout-split-col">
<h3>{t.checkout.step2}</h3>
<div class="payment-options">
<label class="pay-option" style="--brand-color:#009cde; --brand-bg:#003087;">
<span class="pay-icon" style="background:linear-gradient(160deg, #0070ba, #003087); color:#fff;">P</span>
<span>PayPal</span>
<input type="radio" name="pay" value="paypal" checked />
</label>
<label class="pay-option" style="--brand-color:#ffb3c7; --brand-bg:#17120f;">
<span class="pay-icon" style="background:linear-gradient(160deg, #ffc9d8, #ffb3c7); color:#0a0a0a;">K</span>
<span>Klarna</span>
<input type="radio" name="pay" value="klarna" />
</label>
<label class="pay-option" style="--brand-color:#ff9838; --brand-bg:#241f3d;">
<span class="pay-icon pay-icon-cc" style="background:linear-gradient(160deg, #2a2a3d, #14141f);">
<span class="cc-dot cc-dot-a"></span><span class="cc-dot cc-dot-b"></span>
</span>
<span>{t.checkout.creditCard}<span class="pay-sub">{t.checkout.creditCardSub}</span></span>
<input type="radio" name="pay" value="kreditkarte" />
</label>
<label class="pay-option" style="--brand-color:#7fa8c9; --brand-bg:#3b5a76;">
<span class="pay-icon pay-icon-emoji" style="background:linear-gradient(160deg, #4d7599, #2c4258);">🏦</span>
<span>{t.checkout.bankTransfer}</span>
<input type="radio" name="pay" value="ueberweisung" />
</label>
</div>
<div class="pay-connect">
<div class="pay-panel" data-panel="paypal">
<p>{t.checkout.payPalHint}</p>
<div id="paypal-button-container"></div>
<div class="pay-card" style="--brand-color:#009cde; --brand-bg:#003087;">
<label class="pay-option">
<span class="pay-icon" style="background:linear-gradient(160deg, #0070ba, #003087); color:#fff;">P</span>
<span>PayPal</span>
<input type="radio" name="pay" value="paypal" checked />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.payPalHint}</p>
<div id="paypal-button-container"></div>
</div>
</div>
<div class="pay-panel" data-panel="klarna" hidden>
<p>{t.checkout.klarnaHint}</p>
<button type="button" class="btn btn-outline pay-connect-btn" id="klarna-connect">{t.checkout.klarnaConnect}</button>
<p class="pay-connect-status" id="klarna-status"></p>
<div class="pay-card" style="--brand-color:#ffb3c7; --brand-bg:#17120f;">
<label class="pay-option">
<span class="pay-icon" style="background:linear-gradient(160deg, #ffc9d8, #ffb3c7); color:#0a0a0a;">K</span>
<span>Klarna</span>
<input type="radio" name="pay" value="klarna" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.klarnaHint}</p>
<button type="button" class="btn btn-outline pay-connect-btn" id="klarna-connect">{t.checkout.klarnaConnect}</button>
<p class="pay-connect-status" id="klarna-status"></p>
</div>
</div>
<div class="pay-panel" data-panel="kreditkarte" hidden>
<p>{t.checkout.cardHint}</p>
<div class="card-fields">
<div>
<label for="cc-number">{t.checkout.cardNumber}</label>
<input type="text" id="cc-number" inputmode="numeric" placeholder="1234 5678 9012 3456" maxlength="19" />
</div>
<div class="grid grid-2">
<div><label for="cc-expiry">{t.checkout.cardExpiry}</label><input type="text" id="cc-expiry" placeholder="MM/YY" maxlength="5" /></div>
<div><label for="cc-cvc">{t.checkout.cardCvc}</label><input type="text" id="cc-cvc" inputmode="numeric" placeholder="123" maxlength="4" /></div>
<div class="pay-card" style="--brand-color:#ff9838; --brand-bg:#241f3d;">
<label class="pay-option">
<span class="pay-icon pay-icon-cc" style="background:linear-gradient(160deg, #2a2a3d, #14141f);">
<span class="cc-dot cc-dot-a"></span><span class="cc-dot cc-dot-b"></span>
</span>
<span>{t.checkout.creditCard}<span class="pay-sub">{t.checkout.creditCardSub}</span></span>
<input type="radio" name="pay" value="kreditkarte" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.cardHint}</p>
<div class="card-fields">
<div>
<label for="cc-number">{t.checkout.cardNumber}</label>
<input type="text" id="cc-number" inputmode="numeric" placeholder="1234 5678 9012 3456" maxlength="19" />
</div>
<div class="grid grid-2">
<div><label for="cc-expiry">{t.checkout.cardExpiry}</label><input type="text" id="cc-expiry" placeholder="MM/YY" maxlength="5" /></div>
<div><label for="cc-cvc">{t.checkout.cardCvc}</label><input type="text" id="cc-cvc" inputmode="numeric" placeholder="123" maxlength="4" /></div>
</div>
</div>
</div>
</div>
<div class="pay-panel" data-panel="ueberweisung" hidden>
<p>{t.checkout.bankHintReal}</p>
<div class="bank-details" id="bank-details"></div>
<div class="pay-card" style="--brand-color:#7fa8c9; --brand-bg:#3b5a76;">
<label class="pay-option">
<span class="pay-icon pay-icon-emoji" style="background:linear-gradient(160deg, #4d7599, #2c4258);">🏦</span>
<span>{t.checkout.bankTransfer}</span>
<input type="radio" name="pay" value="ueberweisung" />
</label>
<div class="pay-panel-inline">
<p>{t.checkout.bankHintReal}</p>
<div class="bank-details" id="bank-details"></div>
</div>
</div>
</div>
@@ -191,17 +196,8 @@ import { bankverbindung, bankverbindungVollstaendig } from "../../../data/bankve
renderSummary();
landSelect.addEventListener("change", renderSummary);
// Zahlungsart-Auswahl: pro Methode ein Panel, nur die gewählte ist sichtbar. Macht die
// Auswahl sofort "aktionabel" statt ein reines Formularfeld zu sein.
const payPanels = document.querySelectorAll(".pay-panel");
function showPayPanel(method) {
payPanels.forEach((p) => { p.hidden = p.dataset.panel !== method; });
}
document.querySelectorAll('input[name="pay"]').forEach((radio) => {
radio.addEventListener("change", () => showPayPanel(radio.value));
});
const initialPay = document.querySelector('input[name="pay"]:checked');
if (initialPay) showPayPanel(initialPay.value);
// Zahlungsart-Auswahl: der "Verbinden"-Bereich jeder Karte klappt rein über CSS
// (:has(input:checked)) sofort auf, sobald man die Karte anklickt — kein JS, keine Verzögerung.
// PayPal: echte PayPal Smart Buttons über das offizielle JS-SDK (Sandbox-Client-ID "sb" —
// kostenlos, ohne eigenes Konto testbar). Klick öffnet den echten PayPal-Login-Popup. Für den
@@ -38,20 +38,20 @@ const weitere = echtProdukte.slice(1);
{featured ? (
<section class="section-tight">
<div class="container grid grid-2 intro">
<div class="portrait-frame portrait">
<a class="portrait-frame portrait" href={`/fr/produkt/${featured.slug}/`} aria-label={featured.name[lang]}>
{featured.bilder && featured.bilder.length > 0 ? (
<img class="product-photo" src={featured.bilder[0]} alt={featured.name[lang]} loading="lazy" />
) : (
<div class="img-placeholder" role="img" aria-label={featured.name[lang]}></div>
)}
</div>
</a>
<div>
{sub.vorstellung && <span class="eyebrow">{sub.vorstellung[lang].split("\n")[0]}</span>}
<h2>{featured.name[lang]}</h2>
<p class="lead">{featured.beschreibung[lang]}</p>
<h2><a href={`/fr/produkt/${featured.slug}/`}>{featured.name[lang]}</a></h2>
<p class="lead">{sub.vorstellung ? sub.vorstellung[lang].split("\n")[1] : featured.beschreibung[lang]}</p>
{sub.mehrLink && (
<div class="character-more">
<p>Tu veux en savoir plus sur {sub.name[lang]} ?</p>
<p>Si tu veux en savoir plus sur moi, clique</p>
<a class="btn btn-outline" href={sub.mehrLink} target="_blank" rel="noopener">ici →</a>
</div>
)}
@@ -66,7 +66,7 @@ const weitere = echtProdukte.slice(1);
{sub.vorstellung[lang].split("\n").map((line) => <p>{line}</p>)}
{sub.mehrLink && (
<div class="character-more">
<p>Tu veux en savoir plus sur {sub.name[lang]} ?</p>
<p>Si tu veux en savoir plus sur moi, clique</p>
<a class="btn btn-outline" href={sub.mehrLink} target="_blank" rel="noopener">ici →</a>
</div>
)}
@@ -41,20 +41,20 @@ const weitere = echtProdukte.slice(1);
{featured ? (
<section class="section-tight">
<div class="container grid grid-2 intro">
<div class="portrait-frame portrait">
<a class="portrait-frame portrait" href={`/produkt/${featured.slug}/`} aria-label={featured.name[lang]}>
{featured.bilder && featured.bilder.length > 0 ? (
<img class="product-photo" src={featured.bilder[0]} alt={featured.name[lang]} loading="lazy" />
) : (
<div class="img-placeholder" role="img" aria-label={featured.name[lang]}></div>
)}
</div>
</a>
<div>
{sub.vorstellung && <span class="eyebrow">{sub.vorstellung[lang].split("\n")[0]}</span>}
<h2>{featured.name[lang]}</h2>
<p class="lead">{featured.beschreibung[lang]}</p>
<h2><a href={`/produkt/${featured.slug}/`}>{featured.name[lang]}</a></h2>
<p class="lead">{sub.vorstellung ? sub.vorstellung[lang].split("\n")[1] : featured.beschreibung[lang]}</p>
{sub.mehrLink && (
<div class="character-more">
<p>Du willst mehr über {sub.name[lang]} erfahren?</p>
<p>Wenn du mehr über mich erfahren möchtest, dann klicke</p>
<a class="btn btn-outline" href={sub.mehrLink} target="_blank" rel="noopener">hier →</a>
</div>
)}
@@ -69,7 +69,7 @@ const weitere = echtProdukte.slice(1);
{sub.vorstellung[lang].split("\n").map((line) => <p>{line}</p>)}
{sub.mehrLink && (
<div class="character-more">
<p>Du willst mehr über {sub.name[lang]} erfahren?</p>
<p>Wenn du mehr über mich erfahren möchtest, dann klicke</p>
<a class="btn btn-outline" href={sub.mehrLink} target="_blank" rel="noopener">hier →</a>
</div>
)}