feat(legal): readable legal pages and corrected legal texts

Legal pages rendered admin text as bare paragraphs. LegalPage now has a
honeycomb header, a sticky table of contents with scroll tracking (a
collapsible one on mobile), anchor links, a reading progress bar and a
revision date pulled from a "Stand:" line. lib/legal-blocks.ts derives
lists, cookie/provider entries with labelled facts and safe links from
plain text, so the pages stay editable in the admin without markup.

Legal corrections (German law as of 2026):
- Widerrufsbelehrung now follows the official model (Anlage 1 und 2 zu
  Art. 246a EGBGB): recipient name/address/e-mail filled from company
  data, deadline rule, return period, refund details, diminished value
  and the model withdrawal form. The incomplete notice extended the
  withdrawal period to up to 12 months and 14 days. Honey is no longer
  declared perishable.
- Impressum: TMG references replaced by DDG; editorial contact gains an
  address.
- Datenschutz: removes the self-hosted vs. hosting-provider
  contradiction, adds PayPal/Klarna, reviews, back-in-stock
  notifications, storage period, no automated decisions, withdrawal of
  consent and the Art. 21 objection notice; newsletter double opt-in.
- AGB: payment methods and delivery area point to the live shipping
  page; adds contract-text and input-correction information.
- Cookie policy: storage period and provider for every entry.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Nick SzaunigandClaude Opus 5.5 committed 2026-09-26 07:02:12 +02:00
1 parent 86cc0ad310
commit 4ab1a7edae
9 files changed
+707 -84

No files matched your search

+64 -23
View File
@@ -170,6 +170,8 @@ export const en: Dictionary = {
},
legalPage: {
reviewNotice: "",
tocLabel: "Contents",
revisionLabel: "Last updated",
},
notFoundPage: {
title: "This page doesn't exist, at least not anymore.",
@@ -200,7 +202,7 @@ export const en: Dictionary = {
emailLabel: "Email",
sections: [
{
heading: "Information pursuant to § 5 TMG (German Telemedia Act)",
heading: "Information pursuant to § 5 DDG (German Digital Services Act)",
paragraphs: [
"Owner: Nick Rosenlöcher",
"Legal form: sole proprietorship (Einzelunternehmen)",
@@ -215,13 +217,13 @@ export const en: Dictionary = {
{
heading: "Editorially Responsible",
paragraphs: [
"Responsible for editorial content pursuant to § 18(2) MStV (German Interstate Media Treaty), including the articles in our \"Honey Knowledge\" section: Nick Rosenlöcher.",
"Responsible for editorial content pursuant to § 18(2) MStV (German Interstate Media Treaty), including the articles in our \"Honey Knowledge\" section: Nick Rosenlöcher, address as above.",
],
},
{
heading: "Liability for Content",
paragraphs: [
"As a service provider, we are responsible for our own content on these pages under the general laws pursuant to § 7(1) TMG. However, pursuant to §§ 8 to 10 TMG, we as a service provider are not obligated to monitor transmitted or stored third-party information or to investigate circumstances that indicate unlawful activity. Obligations to remove or block the use of information under general law remain unaffected. However, liability in this regard is only possible from the point in time at which we become aware of a specific infringement. Upon becoming aware of any such infringements, we will remove the relevant content immediately.",
"As a service provider, we are responsible for our own content on these pages under the general laws pursuant to § 7(1) DDG. However, pursuant to §§ 8 to 10 DDG, we as a service provider are not obligated to monitor transmitted or stored third-party information or to investigate circumstances that indicate unlawful activity. Obligations to remove or block the use of information under general law remain unaffected. However, liability in this regard is only possible from the point in time at which we become aware of a specific infringement. Upon becoming aware of any such infringements, we will remove the relevant content immediately.",
],
},
{
@@ -252,7 +254,7 @@ export const en: Dictionary = {
{
heading: "1. Data Controller",
paragraphs: [
"Based on the size and nature of our business, we do not believe we are required to appoint a data protection officer under § 38 BDSG. For any data protection questions, please use the contact address given in our legal notice.",
"Based on the size and nature of our business, we do not believe we are required to appoint a data protection officer under § 38 BDSG. For any data protection questions, please use the contact address given above.",
],
},
{
@@ -264,7 +266,7 @@ export const en: Dictionary = {
{
heading: "3. Server Log Files When Visiting the Website",
paragraphs: [
"When you access our website, our hosting provider automatically collects technical access data (e.g. IP address, date and time of access, page accessed, browser type, referrer URL) in what are known as server log files. This processing is technically necessary to provide the website (Art. 6(1)(f) GDPR) and is deleted automatically after a short time.",
"When you access our website, we automatically collect on our server technical access data (e.g. IP address, date and time of access, page accessed, browser type, referrer URL) in what are known as server log files. This processing is technically necessary to provide the website (Art. 6(1)(f) GDPR) The log files are not combined with other data and are deleted automatically once they are no longer needed for security and error analysis.",
],
},
{
@@ -273,14 +275,15 @@ export const en: Dictionary = {
"For shipping, we pass your name and delivery address to our shipping provider DHL (DHL Paket GmbH, Bonn, Germany). If you choose delivery to a Packstation or branch, the location number you selected is added. If you search for a Packstation during checkout, the town or postcode you enter is sent to DHL to perform that search. When you check your shipment under “Track order”, we request its status from DHL using the tracking number and the delivery postcode and show it to you directly on our site. Legal basis: Art. 6(1)(b) GDPR.",
"When you place an order, we collect the data necessary for contract, payment, and shipping processing (name, address, email, phone number if provided, and the items ordered). The legal basis is Art. 6(1)(b) GDPR (contract performance).",
"Payments are processed by our payment provider, Stripe Payments Europe, Ltd. The data necessary for payment processing is transmitted to Stripe for this purpose. Stripe's privacy policy also applies (stripe.com/privacy). Where this involves transferring data to Stripe-affiliated companies outside the EU/EEA (in particular Stripe, Inc. in the USA), this is done on the basis of EU Standard Contractual Clauses pursuant to Art. 46 GDPR.",
"If you choose PayPal or Klarna in the payment step, you are redirected to the respective provider and the order data required for payment is transmitted to them: PayPal (Europe) S.à r.l. et Cie, S.C.A., 22–24 Boulevard Royal, L-2449 Luxembourg, or Klarna Bank AB (publ), Sveavägen 46, 111 34 Stockholm, Sweden. These providers may carry out their own checks, e.g. of identity or creditworthiness; they are responsible for these themselves and their privacy notices apply. Legal basis: Art. 6(1)(b) GDPR.",
"Order and invoice data is retained for the legally required period due to commercial and tax record-keeping obligations (§ 257 HGB, § 147 AO of German law).",
],
},
{
heading: "5. Customer Account",
paragraphs: [
"You can alternatively sign in with a Microsoft account (Microsoft Entra ID). You are redirected to Microsoft and sign in there; we never receive a password, only your email address and name in order to match your customer account. Which data Microsoft itself processes during sign-in is governed by Microsoft's privacy notice. The provider is Microsoft Ireland Operations Limited; a transfer to Microsoft Corporation in the USA may take place. Microsoft is certified under the EU-US Data Privacy Framework. Legal basis: Art. 6(1)(b) GDPR.",
"If you create a customer account, we store the data you provide (name, email, password encrypted as a hash) as well as any delivery addresses you optionally save, to give you access to your order history, invoices, and a faster checkout. The legal basis is Art. 6(1)(b) GDPR. You can have your account and associated data deleted at any time via an informal request to us.",
"You can alternatively sign in with a Microsoft account (Microsoft Entra ID). You are redirected to Microsoft and sign in there; we never receive a password, only your email address and name in order to match your customer account. Which data Microsoft itself processes during sign-in is governed by Microsoft's privacy notice. The provider is Microsoft Ireland Operations Limited; a transfer to Microsoft Corporation in the USA may take place. Microsoft is certified under the EU-US Data Privacy Framework. Legal basis: Art. 6(1)(b) GDPR.",
"A technically necessary cookie is set for login; see our Cookie Policy.",
],
},
@@ -288,6 +291,7 @@ export const en: Dictionary = {
heading: "6. Newsletter (Harvest Mail)",
paragraphs: [
"If you sign up for our harvest mail, we use your email address exclusively to send information about new harvests. The legal basis is your consent (Art. 6(1)(a) GDPR). You can unsubscribe at any time via the link in every email or through your customer account.",
"Sign-up uses a double opt-in: you are only added once you click the link in our confirmation email. Unsubscribing withdraws your consent with effect for the future (Art. 7(3) GDPR). We then keep your address together with the time of unsubscribing so that we can demonstrate your consent and its withdrawal and send you no further harvest mail (Art. 6(1)(f) GDPR).",
],
},
{
@@ -312,14 +316,36 @@ export const en: Dictionary = {
],
},
{
heading: "10. Cookies",
heading: "10. Product Reviews",
paragraphs: [
"If you write a review while signed in, we store the star rating, text, time and the link to your customer account. Once approved by us, the review appears on the product page together with your first name and the date. Legal basis: Art. 6(1)(b) GDPR; the review is kept until you ask us to delete it or your customer account is deleted.",
],
},
{
heading: "11. Back-in-Stock Notification",
paragraphs: [
"If you ask to be notified when a sold-out product is available again, we store your email address, the product and your language in order to send you exactly one notification once it is back in stock. Legal basis: your request (Art. 6(1)(b) GDPR). You can have the request deleted at any time by contacting us.",
],
},
{
heading: "12. Cookies",
paragraphs: ["Details on the cookies used on this website can be found in our Cookie Policy."],
},
{
heading: "11. Your Rights",
heading: "13. Storage Period and Obligation to Provide Data",
paragraphs: [
"We store personal data only as long as necessary for the respective purpose or as required by statutory retention periods (for order and invoice data up to ten years under § 147 AO, § 257 HGB). The data is deleted afterwards.",
"The details required for an order are needed to conclude and perform the contract; without them no order is possible. All other details (e.g. newsletter, reviews) are voluntary.",
"No automated decision-making including profiling within the meaning of Art. 22 GDPR takes place.",
],
},
{
heading: "14. Your Rights",
paragraphs: [
"You have the right to access (Art. 15 GDPR), rectification (Art. 16 GDPR), erasure (Art. 17 GDPR), restriction of processing (Art. 18 GDPR), data portability (Art. 20 GDPR), and objection to processing (Art. 21 GDPR) of your personal data.",
"You also have the right to lodge a complaint with a data protection supervisory authority, e.g. the Bavarian State Office for Data Protection Supervision.",
"You also have the right to lodge a complaint with a data protection supervisory authority, e.g. the Bavarian State Office for Data Protection Supervision (BayLDA), Promenade 18, 91522 Ansbach, Germany, www.lda.bayern.de.",
"If you have given consent, you may withdraw it at any time with effect for the future (Art. 7(3) GDPR). This does not affect the lawfulness of processing carried out before the withdrawal.",
"Right to object: where we process data on the basis of legitimate interests (Art. 6(1)(f) GDPR), you may object at any time on grounds relating to your particular situation (Art. 21(1) GDPR). We will then no longer process the data unless we can demonstrate compelling legitimate grounds. You may object to processing for direct marketing at any time without giving reasons (Art. 21(2) GDPR). An informal message to us is sufficient.",
],
},
],
@@ -337,6 +363,7 @@ export const en: Dictionary = {
heading: "2. Formation of Contract",
paragraphs: [
"The presentation of products in the shop does not constitute a binding offer, but rather a non-binding invitation for you to place an order. By completing an order, you submit a binding offer to purchase, which we accept by confirming it via email or by delivering the goods.",
"Until payment is completed you can correct your entries in the order form at any time; from the payment step, “Back to your details” returns you to the form. The contract is concluded in German. We store the contract text; you receive the order details with the confirmation email, and with a customer account you can view your orders there at any time. You can access, print and save these terms on this page at any time.",
],
},
{
@@ -346,18 +373,18 @@ export const en: Dictionary = {
{
heading: "4. Payment Methods",
paragraphs: [
"We offer PayPal, credit card, Apple Pay, and Google Pay via our payment provider Stripe. Payment by bank transfer is available on request. See our \"Shipping & Payment\" page and our Privacy Policy for details on Stripe.",
"Payment is processed by our payment provider Stripe. The payment methods available (e.g. credit card, SEPA direct debit, Klarna, PayPal, Apple Pay, Google Pay) are shown during checkout and on our \"Shipping & Payment\" page. Payment by bank transfer is available on request.",
"The purchase price is generally due immediately upon ordering (prepayment via the chosen payment method), unless otherwise agreed.",
],
},
{
heading: "5. Delivery and Pickup",
paragraphs: ["We deliver within Germany. Alternatively, goods can be picked up directly from us in Altenmünster by arrangement."],
paragraphs: ["We deliver to the delivery area stated on our \"Shipping & Payment\" page. Alternatively, goods can be picked up directly from us in Altenmünster by arrangement."],
},
{
heading: "6. Right of Withdrawal",
paragraphs: [
"Consumers generally have a statutory right of withdrawal. For details, in particular exceptions for perishable goods such as honey, please see our separate Right of Withdrawal page.",
"Consumers generally have a statutory right of withdrawal. For details, in particular the statutory exceptions, please see our separate Right of Withdrawal page.",
],
},
{
@@ -391,25 +418,39 @@ export const en: Dictionary = {
title: "Right of Withdrawal",
sections: [
{
// Translation of the official German model (see de.ts); the German
// version is the legally binding one.
heading: "Right of Withdrawal",
paragraphs: [
"You have the right to withdraw from this contract within fourteen days without giving any reason. The withdrawal period is fourteen days from the day on which you, or a third party named by you, took possession of the goods.",
"To exercise your right of withdrawal, you must inform us of your decision to withdraw from this contract by means of a clear statement (e.g. by email).",
"You have the right to withdraw from this contract within fourteen days without giving any reason.",
"The withdrawal period is fourteen days from the day on which you, or a third party other than the carrier named by you, took possession of the goods.",
"To exercise your right of withdrawal, you must inform us ({{anbieter}}) of your decision to withdraw from this contract by means of a clear statement (e.g. a letter sent by post or an email). You may use the model withdrawal form below, but it is not obligatory.",
"To meet the withdrawal deadline, it is sufficient for you to send your communication concerning your exercise of the right of withdrawal before the withdrawal period has expired.",
],
},
{
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.
"If you withdraw from this contract, we shall reimburse to you all payments received from you, including the costs of delivery (with the exception of the supplementary costs resulting from your choice of a type of delivery other than the least expensive type of standard delivery offered by us), without undue delay and in any event not later than fourteen days from the day on which we are informed about your decision to withdraw from this contract. We will carry out such reimbursement using the same means of payment as you used for the initial transaction, unless you have expressly agreed otherwise; in any event, you will not incur any fees as a result of such reimbursement.",
"We may withhold reimbursement until we have received the goods back or you have supplied evidence of having sent back the goods, whichever is the earliest.",
"You shall send back the goods or hand them over to us without undue delay and in any event not later than fourteen days from the day on which you communicate your withdrawal from this contract to us. The deadline is met if you send back the goods before the period of fourteen days has expired.",
"You bear the direct cost of returning the goods.",
"You are only liable for any diminished value of the goods resulting from handling other than what is necessary to establish the nature, characteristics and functioning of the goods.",
],
},
{
heading: "Exclusion of the Right of Withdrawal",
paragraphs: [
"The right of withdrawal does not apply to the delivery of goods that can spoil quickly or whose expiry date would soon be exceeded, nor to sealed goods that are not suitable for return for health or hygiene reasons if their seal has been removed after delivery.",
"The right of withdrawal does not apply to contracts for the supply of sealed goods which are not suitable for return due to health protection or hygiene reasons if they were unsealed after delivery (§ 312g(2) No. 3 BGB). This applies in particular to opened honey jars whose tamper-evident seal has been broken.",
],
},
{
heading: "Model withdrawal form",
paragraphs: [
"(Complete and return this form only if you wish to withdraw from the contract.)",
"To: {{anbieter}}",
"- I/We (*) hereby give notice that I/We (*) withdraw from my/our (*) contract of sale of the following goods (*)/for the provision of the following service (*)\n- Ordered on (*)/received on (*)\n- Name of consumer(s)\n- Address of consumer(s)\n- Signature of consumer(s) (only if this form is notified on paper)\n- Date",
"(*) Delete as appropriate.",
],
},
],
@@ -486,17 +527,17 @@ export const en: Dictionary = {
heading: "Local storage (localStorage)",
paragraphs: [
"The following entries are kept in your browser's local storage. Unlike cookies, they are not automatically sent to us with every page request and do not expire on their own: they remain until you delete them (via your browser's “clear site data” setting) or the website removes them. Legal basis: § 25(2) No. 2 TDDDG and Art. 6(1)(b) or (f) GDPR.",
"wabenhain-cart – Your cart (items, quantities, prices). It is only transmitted to us when you submit an order, and it is emptied after a successful order.",
"wabenhain-recently-viewed – The identifiers of up to 6 recently viewed products, so they can be shown to you again on product pages. Only these product identifiers are requested for display; we store no browsing history on our servers.",
"wabenhain-cookie-consent – Your choice in the cookie banner (“Essential only” or “Accept all”), so the banner does not reappear on every visit and we can demonstrate your decision. Legal basis: § 25(2) No. 2 TDDDG and Art. 6(1)(c) GDPR in conjunction with Art. 7(1) GDPR.",
"wabenhain-cart – Your cart (items, quantities, prices). It is only transmitted to us when you submit an order, and it is emptied after a successful order. Storage period: until your next order or until you empty it yourself.",
"wabenhain-recently-viewed – The identifiers of up to 6 recently viewed products, so they can be shown to you again on product pages. Only these product identifiers are requested for display; we store no browsing history on our servers. Storage period: until you clear the site data in your browser.",
"wabenhain-cookie-consent – Your choice in the cookie banner (“Essential only” or “Accept all”), so the banner does not reappear on every visit and we can demonstrate your decision. Storage period: until you change your choice or clear the site data. Legal basis: § 25(2) No. 2 TDDDG and Art. 6(1)(c) GDPR in conjunction with Art. 7(1) GDPR.",
],
},
{
heading: "Third-party cookies",
paragraphs: [
"Stripe (payment processing): Only in the payment step of checkout does your browser load Stripe's payment form. Stripe sets its own cookies for fraud prevention and secure payment processing, in particular __stripe_mid (storage period 1 year) and __stripe_sid (storage period 30 minutes), as well as further cookies within the payment form on Stripe domains. Stripe determines the names and lifetimes of these cookies. Provider: Stripe Payments Europe, Ltd., 1 Grand Canal Street Lower, Dublin 2, Ireland. Data may be transferred to Stripe, Inc. in the USA on the basis of EU standard contractual clauses (Art. 46 GDPR). Legal basis: § 25(2) No. 2 TDDDG and Art. 6(1)(b) GDPR. More information: stripe.com/privacy and stripe.com/legal/cookies-policy.",
"Microsoft (sign-in with a Microsoft account): If you choose “Sign in with Microsoft”, you are redirected to a Microsoft sign-in page. Microsoft (Microsoft Ireland Operations Limited) is responsible for the cookies set there; Microsoft's privacy statement applies. Microsoft sets no cookies on our website.",
"Cloudflare Turnstile (form protection): On pages with forms (sign-in, registration, password reset, two-factor verification, checkout, newsletter, business enquiry, back-in-stock notification), your browser loads a script from challenges.cloudflare.com. It distinguishes input made by humans from input made by automated programs. Your IP address and technical characteristics of your browser are transmitted to Cloudflare, Inc. (USA) in the process. According to the provider, Turnstile sets no advertising cookies and builds no cross-site user profile. Cloudflare is certified under the EU-US Data Privacy Framework. Details are in our privacy policy.",
"Microsoft (sign-in with a Microsoft account): If you choose “Sign in with Microsoft”, you are redirected to a Microsoft sign-in page. Microsoft is responsible for the cookies set there; Microsoft's privacy statement applies. Microsoft sets no cookies on our website. Provider: Microsoft Ireland Operations Limited, One Microsoft Place, South County Business Park, Leopardstown, Dublin 18, Ireland.",
"Cloudflare Turnstile (form protection): On pages with forms (sign-in, registration, password reset, two-factor verification, checkout, newsletter, business enquiry, back-in-stock notification), your browser loads a script from challenges.cloudflare.com. It distinguishes input made by humans from input made by automated programs. Your IP address and technical characteristics of your browser are transmitted to Cloudflare, Inc. (USA) in the process. According to the provider, Turnstile sets no advertising cookies and builds no cross-site user profile. Cloudflare is certified under the EU-US Data Privacy Framework. Provider: Cloudflare, Inc., 101 Townsend Street, San Francisco, CA 94107, USA. Legal basis: § 25(2) No. 2 TDDDG and Art. 6(1)(f) GDPR. More information: see the “Cloudflare Turnstile” section of our privacy policy.",
"Google reviews: We retrieve the reviews on our homepage server-side via the Google Places API. Your browser does not connect to Google, and Google sets no cookie.",
],
},