"use client"; import type { ReactNode } from "react"; import Link from "next/link"; import Image from "next/image"; import { Reveal } from "./Reveal"; import { useNewsletterSignup } from "../lib/useNewsletterSignup"; // Same lock icon + copy as /challenge's and /newsletter's EmailCapture — // unified across all newsletter-signup forms instead of each having its // own wording/color for this trust note. function LockIcon() { return ( ); } type NewsletterProps = { title?: ReactNode; description?: string; }; /** * Reused as-is (same bordered/muted panel + icon-decoration + form * pattern) on both Home and /newsletter (the "Impulse & Tipps" page) — * their Figma frames use the exact same newsletter-inner component * instance, just with different copy, so title/description are props * instead of a second near-duplicate component. */ export function Newsletter({ title = "Kleine Impulse – große Wirkung", description = "Melde dich an und bekomme meine Sonntags-Impulse ab jetzt jede Woche direkt in dein Postfach: kurze Gedanken, praktische Impulse und kleine Anstöße für mehr Klarheit im Alltag.", }: NewsletterProps = {}) { const { email, emailError, consent, handleConsentChange, status, error, successMessage, emailRef, handleEmailChange, handleEmailBlur, handleSubmit } = useNewsletterSignup("newsletter-page"); return (
{/* Outer section padding — same fluid horizontal padding as all other sections */}
{/* max-w-[1280px] mx-auto — the consistent default width for this card, matching /lebensuhr's own newsletter-style "Bottom CTA" section (same 1280px cap Footer.tsx already uses) and every other narrow-viewport-friendly section on the site. Previously unbounded here, so on wide desktop viewports this card stretched edge-to-edge while /lebensuhr's version stayed centered and noticeably narrower — reported 2026-07-29. */} {/* Rounded card: cream bg, stacks below sm (moved down from the old md:) */} {/* py-8 at every breakpoint, not just below sm (was sm:py-0, relying purely on items-center + the taller column's own height to create top/bottom breathing room) — the form column (input, checkbox+label, privacy note) can be as tall as or taller than the copy column depending on viewport width, so centering alone left no slack to distribute and the input/ "Keine Werbung" note sat flush against the card's top/bottom edge. */} {/* Left: copy — fixed width from sm+ so the form always gets the remaining space. Icon+text stacked (icon on top, centered) below sm: — side by side they squeezed the text into a narrow column on a phone (icon width + gap eating most of the card's inner width), wrapping awkwardly, and the same squeeze reappeared through the whole tablet range (640-1023px) once the outer card's own sm:flex-row already put this copy column next to the form — row layout for icon+text is only comfortable once there's real room, i.e. lg+. Left-aligned (not centered) from sm up — only true mobile keeps the centered treatment. */}
{/* Decorative envelope icon, tilted -4° as per design. w-[4rem], not w-16 — this project's --spacing-16 is a fluid token (floors to 40px below 768px, see globals.css), so pairing w-16 with the fixed h-[3.438rem] squished the icon to a 40:55 box on mobile instead of the SVG's native 64:55.0096 (it has preserveAspectRatio="none", so it actually stretches to whatever box it's given — fixed 2026-07-24). */}
{/* Heading + body */}

{title}

{description}

{/* Right: form — takes remaining space, centered vertically from sm+ */}
{status === "success" ? (

{successMessage}

) : (
{/* Input + submit button — stacked below lg:, a deliberate exception to the site's sm: (640px) structural consolidation, not a leftover of it. The card above already goes side-by-side at sm: with a fixed-width copy column (--newsletter-copy-width), which only leaves ~128px for this form column at 640px and ~197px at 768px — not enough room for input+button side by side even at the new, lower floor. Stacked through the whole 640-1023px range instead, side by side again once the form column has real room (≈333px) at lg:. */}
handleEmailChange(e.target.value)} onBlur={(e) => handleEmailBlur(e.target.value)} placeholder="Deine E-Mail-Adresse" aria-invalid={Boolean(emailError)} className={`flex-1 min-w-0 bg-bg-white border rounded-sm px-6 py-3 text-body text-text-muted font-normal outline-none transition-colors ${ emailError ? "border-red-600 focus:border-red-600" : "border-border focus:border-brand" }`} />
{emailError && (

{emailError}

)} {/* Consent checkbox — required since this signup's legal basis is consent (email marketing), not the "Ich achte auf deine Daten" trust note alone. Same wording/pattern as NewsletterModal's checkbox. */} {status === "error" && (

{error}

)} {/* Privacy note — same icon/copy/color as the other newsletter forms (see /challenge's EmailCapture). */}

Keine Werbung. Jederzeit abbestellbar.

)}
); }