Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5870c60c50 | ||
|
|
cc267ad8d4 |
No files matched your search
@@ -179,16 +179,27 @@ export default async function ProductDetailPage(
|
||||
// Gesetzliches Widerrufsrecht (siehe Widerrufsbelehrung): vierzehn Tage
|
||||
// ab Erhalt der Ware, Rueckgabe per Versand.
|
||||
//
|
||||
// "returnFees" fehlt hier bewusst: wer die Kosten der Ruecksendung
|
||||
// traegt, ist in der Widerrufsbelehrung nicht geregelt. Eine Annahme an
|
||||
// dieser Stelle waere eine Preisangabe gegenueber Google, die der Shop
|
||||
// nirgends zusagt.
|
||||
// returnFees stand hier frueher nicht, weil die Widerrufsbelehrung
|
||||
// nichts zu den Ruecksendekosten sagte. Jetzt sagt sie es: der Kaeufer
|
||||
// traegt sie (Mustersatz nach § 357 Abs. 6 BGB). ReturnFeesCustomer-
|
||||
// Responsibility ist dafuer der richtige Wert und braucht — anders als
|
||||
// ReturnShippingFees — keinen Betrag, was hier auch gar nicht ginge:
|
||||
// die Ruecksendung laeuft ueber den Kaeufer, nicht ueber unser
|
||||
// Versandkonto.
|
||||
//
|
||||
// Dass wir bei mangelhafter Ware die Kosten uebernehmen (siehe
|
||||
// "Versand und Zahlung" → "Rücksendung"), bleibt hier bewusst
|
||||
// unabgebildet: das ist Gewaehrleistung, nicht Ruecknahmepolitik, und
|
||||
// schema.org kennt dafuer kein Feld. Der guenstigere Sonderfall
|
||||
// ungenannt zu lassen ist unbedenklich — umgekehrt waere es eine
|
||||
// Zusage, die der Shop nicht generell macht.
|
||||
hasMerchantReturnPolicy: {
|
||||
"@type": "MerchantReturnPolicy",
|
||||
applicableCountry: shippingCountries,
|
||||
returnPolicyCategory: "https://schema.org/MerchantReturnFiniteReturnWindow",
|
||||
merchantReturnDays: 14,
|
||||
returnMethod: "https://schema.org/ReturnByMail",
|
||||
returnFees: "https://schema.org/ReturnFeesCustomerResponsibility",
|
||||
},
|
||||
},
|
||||
...(reviewSummary.count > 0
|
||||
|
||||
@@ -89,6 +89,28 @@ export default async function RootLayout({ children }: LayoutProps<"/">) {
|
||||
className={`${cormorant.variable} ${inter.variable} h-full antialiased`}
|
||||
>
|
||||
<body className="min-h-full flex flex-col bg-background text-ink">
|
||||
{/* Rettungsnetz fuer den Fall, dass kein JavaScript laeuft.
|
||||
|
||||
Hero, ScrollReveal und ProductCard starten mit opacity 0 und werden
|
||||
erst per motion/react eingeblendet. Weil diese Startwerte schon im
|
||||
server-gerenderten HTML als inline-style stehen, blieb ohne
|
||||
JavaScript alles unterhalb des Hero-Bildes dauerhaft unsichtbar —
|
||||
kein Teilausfall, sondern der komplette Seiteninhalt. Auf
|
||||
wabenhain.com waren das 38 Elemente.
|
||||
|
||||
!important ist hier notwendig und nicht nachlaessig: es gibt keine
|
||||
andere Moeglichkeit, einen inline-style zu ueberschreiben. Die
|
||||
Regel zielt ausschliesslich auf [data-reveal] — Ein- und
|
||||
Ausblendungen in AnimatePresence (Warenkorb-Schublade, Menue,
|
||||
Cookie-Banner) tragen das Attribut nicht und bleiben verborgen.
|
||||
|
||||
Deckt den Fall "JavaScript deaktiviert" ab. Laedt das Bundle
|
||||
dagegen und schlaegt erst spaeter fehl, greift noscript nicht —
|
||||
dafuer waere ein Zeitgeber noetig, der die Animation im Normalfall
|
||||
stoeren wuerde. */}
|
||||
<noscript>
|
||||
<style>{`[data-reveal]{opacity:1!important;transform:none!important}`}</style>
|
||||
</noscript>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(localBusinessJsonLd).replace(/</g, "\\u003c") }}
|
||||
|
||||
@@ -62,6 +62,17 @@ export default async function VersandZahlungPage() {
|
||||
heading: t.versandZahlungPage.deliveryTimeHeading,
|
||||
paragraphs: [t.versandZahlungPage.deliveryTimeText],
|
||||
},
|
||||
{
|
||||
// Die Widerrufsbelehrung nennt nur den amtlichen Mustersatz ("Du
|
||||
// traegst die unmittelbaren Kosten der Ruecksendung"), weil eine
|
||||
// Abweichung vom Muster dessen Gesetzlichkeitsfiktion kostet. Die
|
||||
// Ausnahme fuer mangelhafte Ware gehoert ohnehin nicht dorthin: sie
|
||||
// folgt aus der Gewaehrleistung (§ 439 Abs. 2 BGB) und gilt
|
||||
// unabhaengig davon, ob widerrufen wird. Hier steht beides
|
||||
// nebeneinander, wo Kaeufer vor dem Kauf nach Versandfragen suchen.
|
||||
heading: t.versandZahlungPage.returnsHeading,
|
||||
paragraphs: [t.versandZahlungPage.returnsText, t.versandZahlungPage.returnsDefectText],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -119,18 +119,18 @@ export function Hero({
|
||||
variants={itemContainerVariants}
|
||||
>
|
||||
<motion.p
|
||||
variants={itemVariants}
|
||||
data-reveal="" variants={itemVariants}
|
||||
className="tracking-wide-caps text-xs text-honey-light mb-4"
|
||||
>
|
||||
{location}
|
||||
</motion.p>
|
||||
<motion.h1 variants={itemVariants} className="text-4xl md:text-6xl leading-tight">
|
||||
<motion.h1 data-reveal="" variants={itemVariants} className="text-4xl md:text-6xl leading-tight">
|
||||
{t.footer.tagline}
|
||||
</motion.h1>
|
||||
<motion.p variants={itemVariants} className="mt-6 text-cream/85 max-w-md leading-relaxed">
|
||||
<motion.p data-reveal="" variants={itemVariants} className="mt-6 text-cream/85 max-w-md leading-relaxed">
|
||||
{intro}
|
||||
</motion.p>
|
||||
<motion.div variants={itemVariants} className="mt-10 flex flex-wrap gap-4">
|
||||
<motion.div data-reveal="" variants={itemVariants} className="mt-10 flex flex-wrap gap-4">
|
||||
<LinkButton href="/shop">{t.home.hero.ctaPrimary}</LinkButton>
|
||||
<LinkButton
|
||||
href="/imkerei"
|
||||
@@ -140,7 +140,7 @@ export function Hero({
|
||||
{t.home.hero.ctaSecondary}
|
||||
</LinkButton>
|
||||
</motion.div>
|
||||
<motion.p variants={itemVariants} className="mt-8 text-xs text-cream/60 tracking-wide">
|
||||
<motion.p data-reveal="" variants={itemVariants} className="mt-8 text-xs text-cream/60 tracking-wide">
|
||||
{footnote}
|
||||
</motion.p>
|
||||
</motion.div>
|
||||
|
||||
@@ -178,6 +178,8 @@ export function ProductCard({
|
||||
|
||||
return (
|
||||
<motion.article
|
||||
// Siehe scroll-reveal.tsx: Gegenstueck zum noscript-Block im Root-Layout.
|
||||
data-reveal=""
|
||||
initial={{ opacity: 0, y: 16 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: "-60px" }}
|
||||
|
||||
@@ -23,6 +23,12 @@ export function ScrollReveal({
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
// Markiert dieses Element als "startet unsichtbar und wird per
|
||||
// JavaScript eingeblendet". Der noscript-Block im Root-Layout hebt genau
|
||||
// darueber die Startwerte wieder auf — ohne das Attribut muesste er
|
||||
// blind auf [style*="opacity:0"] zielen und traefe damit auch
|
||||
// Ein-/Ausblendungen, die bewusst verborgen bleiben sollen.
|
||||
data-reveal=""
|
||||
className={className}
|
||||
initial={shouldReduceMotion ? false : { opacity: 0, y }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
|
||||
@@ -373,6 +373,16 @@ export const de: Dictionary = {
|
||||
heading: "Folgen des Widerrufs",
|
||||
paragraphs: [
|
||||
"Wenn du diesen Vertrag widerrufst, erstatten wir dir alle Zahlungen, die wir von dir erhalten haben, unverzüglich und spätestens binnen vierzehn Tagen ab dem Tag zurück, an dem die Mitteilung über deinen Widerruf bei uns eingegangen ist.",
|
||||
// Wortlaut aus der amtlichen Muster-Widerrufsbelehrung (Anlage 1 zu
|
||||
// Art. 246a § 1 Abs. 2 EGBGB), bewusst unveraendert uebernommen.
|
||||
// Ohne diese Information traegt nach § 357 Abs. 6 BGB der Verkaeufer
|
||||
// die Ruecksendekosten — die Belehrung selbst ist die Voraussetzung
|
||||
// dafuer, sie dem Kaeufer auferlegen zu duerfen. Die Ausnahme fuer
|
||||
// mangelhafte Ware steht bewusst NICHT hier: das ist Gewaehrleistung
|
||||
// (§ 439 BGB) und damit ein anderes Recht als der Widerruf; eine
|
||||
// Abweichung vom Muster kostet dessen Gesetzlichkeitsfiktion. Sie
|
||||
// steht stattdessen unter "Versand und Zahlung" → "Rücksendung".
|
||||
"Du trägst die unmittelbaren Kosten der Rücksendung der Waren.",
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -398,6 +408,11 @@ export const de: Dictionary = {
|
||||
paymentText: "Wir bieten Kreditkarte, SEPA-Lastschrift, Klarna, PayPal, Apple Pay und Google Pay über unseren Zahlungsdienstleister Stripe an. Eine Zahlung per Überweisung ist auf Anfrage möglich.",
|
||||
deliveryTimeHeading: "Lieferzeit",
|
||||
deliveryTimeText: "Die übliche Lieferzeit innerhalb Deutschlands beträgt 2–4 Werktage nach Zahlungseingang.",
|
||||
returnsHeading: "Rücksendung",
|
||||
returnsText:
|
||||
"Die unmittelbaren Kosten der Rücksendung trägt der Käufer. Das gilt für die Ausübung des Widerrufsrechts, also wenn du eine einwandfreie Ware zurückgibst.",
|
||||
returnsDefectText:
|
||||
"Davon ausgenommen ist mangelhafte Ware: liegt ein Mangel vor, der auf die Produktion oder auf uns als Verkäufer zurückzuführen ist, übernehmen wir die Kosten der Rücksendung vollständig. Melde dich in diesem Fall einfach bei uns, bevor du die Ware zurückschickst.",
|
||||
},
|
||||
cookieRichtliniePage: {
|
||||
title: "Cookie-Richtlinie",
|
||||
|
||||
@@ -373,6 +373,9 @@ export const en: Dictionary = {
|
||||
heading: "Consequences of Withdrawal",
|
||||
paragraphs: [
|
||||
"If you withdraw from this contract, we will refund all payments we received from you without undue delay, and no later than fourteen days from the day on which we received notice of your withdrawal.",
|
||||
// Siehe Begruendung in de.ts — Wortlaut der amtlichen
|
||||
// Muster-Widerrufsbelehrung, hier nur uebersetzt.
|
||||
"You bear the direct cost of returning the goods.",
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -398,6 +401,11 @@ export const en: Dictionary = {
|
||||
paymentText: "We offer credit card, SEPA direct debit, Klarna, PayPal, Apple Pay, and Google Pay via our payment provider Stripe. Payment by bank transfer is available on request.",
|
||||
deliveryTimeHeading: "Delivery Time",
|
||||
deliveryTimeText: "Typical delivery time within Germany is 2–4 business days after payment is received.",
|
||||
returnsHeading: "Returns",
|
||||
returnsText:
|
||||
"You bear the direct cost of returning the goods. This applies when you exercise your right of withdrawal, meaning you return goods that are in perfect condition.",
|
||||
returnsDefectText:
|
||||
"Defective goods are excluded from this: if a defect originates in production or is otherwise attributable to us as the seller, we cover the full cost of the return. In that case simply contact us before sending the goods back.",
|
||||
},
|
||||
cookieRichtliniePage: {
|
||||
title: "Cookie Policy",
|
||||
|
||||
@@ -234,6 +234,15 @@ export interface Dictionary {
|
||||
paymentText: string;
|
||||
deliveryTimeHeading: string;
|
||||
deliveryTimeText: string;
|
||||
/**
|
||||
* Wer die Ruecksendekosten traegt. Steht hier und nicht in der
|
||||
* Widerrufsbelehrung, weil die Ausnahme fuer mangelhafte Ware
|
||||
* Gewaehrleistung ist (§ 439 BGB) und nicht Widerruf — siehe Kommentar
|
||||
* bei widerrufPage in de.ts.
|
||||
*/
|
||||
returnsHeading: string;
|
||||
returnsText: string;
|
||||
returnsDefectText: string;
|
||||
};
|
||||
cookieRichtliniePage: {
|
||||
title: string;
|
||||
|
||||
Reference in new issue
Block a user