feat(newsletter, checkout): add consent links, unify trust-note styling, optimize images

Every email-signup form (Home/newsletter Newsletter section, /newsletter
hero, /challenge, the Newsletter overlay) now links "Datenschutzerklärung"
to /datenschutz next to its consent checkbox, opened in a new tab so a
partially filled form isn't lost. Checkout gets an equivalent AGB +
Datenschutzerklärung note under the order button, and the Versand
modal's Widerrufsbelehrung link also opens in a new tab.

Unified the "Keine Werbung. Jederzeit abbestellbar." trust note (icon +
#888 copy) across all newsletter forms, matching /challenge's existing
style instead of each form having its own wording/color.

Also converted the remaining raw <img> tags in these files to next/image
per the no-img-element lint rule (bandwidth/LCP).
This commit is contained in:
Marco
2026-07-21 11:15:44 +00:00
parent a72aea1070
commit cc9da6ac6d
6 changed files with 159 additions and 30 deletions
+44 -12
View File
@@ -1,5 +1,6 @@
import type { Metadata } from "next";
import Link from "next/link";
import Image from "next/image";
import { Footer } from "../components/Footer";
import { Reveal, RevealGroup, RevealItem } from "../components/Reveal";
@@ -154,6 +155,28 @@ function EmailCapture({ buttonLabel = "Challenge starten" }: { buttonLabel?: str
{buttonLabel}
</button>
</div>
{/* Consent checkbox — this signup's legal basis is consent (email
marketing), same wording as the other newsletter forms; colors
match this page's own hardcoded palette instead of the shared
design tokens, consistent with the rest of the page. */}
<label className="flex gap-2 items-start cursor-pointer">
<input
type="checkbox"
className="size-4 shrink-0 mt-0.5 rounded-xs border border-[#d9d9d9] accent-[#f6a701]"
/>
<span className="text-[0.8rem] text-[#444] leading-normal">
Ich akzeptiere die{" "}
<Link
href="/datenschutz"
target="_blank"
rel="noopener noreferrer"
className="underline hover:text-[#f6a701]"
>
Datenschutzerklärung
</Link>
.
</span>
</label>
<p className="flex items-center gap-1.5 text-[0.8rem] text-[#888]">
<LockIcon />
Keine Werbung. Jederzeit abbestellbar.
@@ -241,10 +264,12 @@ export default function ChallengePage() {
todo-cards hero images; delay={0.15} mirrors their text→image
stagger. */}
<Reveal className="hidden lg:block group flex-1 relative overflow-hidden" delay={0.15}>
<img
<Image
alt="7-Tage-Challenge"
src="/blog-featured.jpg"
className="absolute inset-0 w-full h-full object-cover object-center pointer-events-none transition-transform duration-500 group-hover:scale-105"
fill
sizes="48vw"
className="object-cover object-center pointer-events-none transition-transform duration-500 group-hover:scale-105"
/>
{/* Badge */}
<div className="absolute top-8 right-8 w-[7.5rem] h-[7.5rem] rounded-full bg-white shadow-md flex flex-col items-center justify-center text-center p-3 gap-1">
@@ -293,9 +318,11 @@ export default function ChallengePage() {
// stacked below lg, this page's own structural
// breakpoint) rather than hidden below lg like before.
<div key={`arrow-${i}`} className="flex items-center justify-center shrink-0 lg:mt-5">
<img
<Image
alt=""
src="/icon-arrow-connector.svg"
width={24}
height={24}
className="w-6 h-6 rotate-90 lg:w-10 lg:h-3 lg:rotate-0"
/>
</div>
@@ -324,14 +351,15 @@ export default function ChallengePage() {
{/* Image */}
<Reveal
className="group w-full lg:w-[44%] lg:shrink-0 rounded-xl overflow-hidden"
className="group relative w-full lg:w-[44%] lg:shrink-0 rounded-xl overflow-hidden"
style={{ minHeight: "18rem" }}
>
<img
<Image
alt="Notizbuch"
src="/challenge-content.jpg"
className="w-full h-full object-cover transition-transform duration-500 group-hover:scale-105"
style={{ minHeight: "18rem" }}
fill
sizes="(min-width: 1024px) 44vw, 100vw"
className="object-cover transition-transform duration-500 group-hover:scale-105"
/>
</Reveal>
@@ -389,11 +417,15 @@ export default function ChallengePage() {
</span>
<p className="text-[#222221] text-[0.95rem] leading-[1.6] flex-1 pr-8">{t.quote}</p>
<div className="flex items-center gap-3">
<img
alt={t.name}
src={t.avatar}
className="w-10 h-10 rounded-full object-cover shrink-0 transition-transform duration-300 group-hover:scale-110"
/>
<div className="relative size-10 shrink-0 rounded-full overflow-hidden">
<Image
alt={t.name}
src={t.avatar}
fill
sizes="40px"
className="object-cover transition-transform duration-300 group-hover:scale-110"
/>
</div>
<div>
<p className="font-semibold text-[#222221] text-[0.9rem]">{t.name}</p>
<p className="text-[#777] text-[0.8rem]">{t.role}</p>