- api/checkout/route.ts: authoritative shipping charge is 0 whenever
every cart line opts out via noShippingCost, regardless of the
free-shipping threshold.
- Cart/checkout order summaries: the whole "Versand" line (cost, free-
shipping note, delivery time) is hidden entirely rather than showing
"Kostenlos" — that's a different state from hitting the threshold.
- ProductSpotlight/Pricing/TodoKartenHero: "zzgl. Versand" and delivery-
time hints drop for an exempted product's own page.
- /versand + its shared modal: one clarifying sentence that digital
products are exempt.
- Widerrufsformular link: opens inline in a new tab (no forced download),
arrow icon changed from a download glyph to a plain right arrow to
match.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The "An:" address used to be baked into a hand-crafted PDF and silently
went stale whenever an admin updated the Impressum's Anbieterdaten
without also re-exporting/re-uploading the file by hand — exactly what
happened 2026-07-29. New /api/muster-widerrufsformular route renders it
on-the-fly via @react-pdf/renderer using the same getCompanySettings()
data as AnbieterAngaben.tsx's Impressum block, so the two can never drift
apart again. Disables react-pdf's default hyphenation, which otherwise
split the seller's email address mid-word to fit the line.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- PopIn (Home Hero's brand dot) switched from whileInView to animate — its
translate-based entrance could push the element off-screen on a narrow
phone before the IntersectionObserver ever saw it as visible, leaving it
stuck invisible permanently.
- Hero image: no longer wrapped in Reveal below lg: — whileInView's margin
meant it stayed at opacity:0 (a white gap above the fold) on short mobile
viewports until scrolled. Reveal's fade-in kept from lg: up.
- "→ Label" CTA links (Tools.tsx, Blog.tsx) now use a flex row with the
arrow as its own span instead of a literal inline "→" character, which
doesn't reliably align to the surrounding text's cap-height.
- Replaced icon-arrow-connector.svg with a new shared StepArrow component
(inline SVG) across all three step sections — the old asset's color
couldn't be overridden from outside the SVG file, so it could never
actually become brand-orange. Bigger and better-shaped below the
structural breakpoint per feedback.
- Added MobileSectionTOC (SectionTOC.tsx) — a <details> accordion shown
below lg: on Impressum/Datenschutz/AGB/Widerruf/Versand, which previously
had no on-page navigation aid at all below lg: (the sidebar TOC is
`hidden` entirely there).
- Updated the figma-to-nextjs skill with 8 new dated Gotchas from this
mobile-responsive pass, and expanded Step 6's verification checklist.
- README: new "Mobile responsive pass" section summarizing the above.
payload.ts's mapping functions/types are also imported by "use client"
components (LiveTestimonialsGrid, LivePostContent) — importing
next/headers anywhere in that module made it unbundlable for the client,
breaking the production build. draftMode() is now only ever called in the
Server Component pages themselves; they pass the resulting boolean into
getPostBySlug/getLegalPage/getTestimonials as a plain `draft` option.
Testimonials on /todo-cards, /newsletter, /challenge now come from the new
Payload testimonials collection via a shared TestimonialsGrid component,
instead of 3 separately hardcoded arrays.
Adds Next.js Draft Mode (/api/preview) plus Live-Preview-aware client
wrappers (LiveRichText, LiveTestimonialsGrid, LivePostContent) for posts,
legal pages, and testimonials — mounted only while Draft Mode is enabled,
so ordinary visitors keep getting the plain static components.
Clears every remaining @next/next/no-img-element warning — automatic
responsive srcset, lazy-loading, and format optimization instead of
always loading the original file at full size. Fixed-size icons got
explicit width/height; dynamic-aspect photos got fill inside a
relative wrapper.
- New /widerruf page: CMS-driven content via getLegalPage("widerruf"),
sidebar TOC + "Nachhaltig handeln" callout, TrustRow, and a download
card for the Muster-Widerrufsformular PDF attachment.
- New /agb page, same legal-page shell pattern as Impressum/Datenschutz.
- lib/payload.ts: getLegalPage now also resolves the optional `attachment`
media relation (depth=1) for legal pages that have a downloadable file.
- NewsletterModal: replaced the body overflow/position scroll-lock hacks
(which fought with the sticky Navbar and the global scroll-smooth CSS)
with a wheel/touch event interceptor that never touches scroll position
at all, plus `preventScroll: true` on all modal/drawer focus() calls to
stop the browser's implicit scrollIntoView from nudging the page for
elements near the sticky navbar's reserved scroll-padding-top zone.
Same preventScroll fix applied to VersandModal and the Navbar mobile
drawer for consistency.
- globals.css: scrollbar-gutter: stable, so a modal's overflow:hidden
lock never causes a scrollbar-width layout shift.
- Divider: stagger its reveal animation slightly (delay 0.3s) behind the
section above it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>