The 58%-wide/no-muted-bg rewrite left a large visible gap between
the photo and the quote on wide viewports, and its very wide 4.9:1
photo crop needed heavy object-cover zooming to fill a narrower
column. Reverted to the exact structure already shipped and working
on /not-found (w-[45%] column, 40px edge gradient into bg-muted) —
the only real change kept is a fixed h- instead of min-h-, which is
what actually fixed the original height-mismatch complaint.
Also re-cropped the photo twice: first to match 404-testimonial-
photo.jpg's 2.65:1 aspect ratio (avoids the aggressive cropping/zoom
a too-wide source needs to fill a taller column), then pushed the
top edge down further after finding the crop still included a few
residual pixels of a cream/shadow boundary line from the source
mockup — invisible in a downscaled preview but a visible seam once
the browser scales the 126px-tall source up 2-3x via object-cover.
Also overflows the image 4px past its container (-inset-1 instead of
inset-0) as a defensive measure against sub-pixel gaps in general.
Testimonial band: rebuilt as a proper flexbox two-column layout
(photo column with an explicit width, quote in a flex-1 sibling)
instead of an absolutely-positioned text block offset with
percentage margin/padding — that measured against the row's full
width and, combined with a max-w- on the text box, left almost no
room for the actual text on wide viewports (wrapped to one word per
line). Also dropped the muted-bg box behind the quote and widened
the photo fade to match the actual mockup, which has no separate
colored panel there at all.
Hero: removed the separate big checkmark badge — the 4-step bar
right above it already renders every step as a checkmark, so it was
just repeating that. Added more top spacing to compensate. Dropped
"Deine Bestellung macht sich jetzt auf den Weg zu dir." and added
"inkl. MwSt." under Gesamtbetrag for consistency with /cart and
/checkout.
Wired the new Products.spotlightEyebrow field (CMS-editable "Neu im
Shop" label) through lib/payload.ts into ProductSpotlight.tsx.
Matches the Figma mockup (checkmark hero, order summary card,
delivery-status panel, testimonial band) with the checkout's 4-step
bar inserted (all steps done) and the "Bis dahin: Lass dich
inspirieren" block omitted, per request.
Extracted the step bar into a shared CheckoutSteps component so
/checkout and /bestellbestaetigung don't duplicate it. The actually-
selected shipping cost and payment method are captured into a
sessionStorage snapshot by /checkout's "Jetzt kaufen" click (there's
no real order backend, so this click is what "placing the order"
means here) and read back on the confirmation page — not just
defaulted to the first active method of each, so the receipt matches
what the shopper actually picked. Also tightened the checkout
newsletter-consent copy ("Wenn du zustimmst" instead of "Wenn du
oben zustimmst").
Fixes the dead "Zur Kasse gehen" link on /cart. Built against the actual
Figma frame (page-checkout, node 4761:465, jCCZyh1DGwdjpv1wGge9To):
breadcrumb, 4-step progress stepper (Warenkorb done / Adresse active /
Zahlung+Abschluss upcoming), Rechnungsadresse form, Versandart (real
radio toggle — switching to Express actually updates the shown total),
Zahlungsart (Kreditkarte/PayPal/Überweisung with the real exported
payment-network logos), sidebar order summary reusing the same
cart/products data as /cart, trust bullets, and a newsletter hint box
(divider under the text, not the icon — deliberately different from
/cart's own version per this page's own Figma spec).
No real payment processing — "Jetzt kaufen" links to
/bestellbestaetigung (not yet built) same as the rest of this prototype
site's forms (cart, newsletter signup) don't hit a real backend either.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- app/blog/[slug]/page.tsx: article header (category/readTime, Playfair
display title, excerpt, byline), full-bleed hero image, RichText body,
"Passend dazu: ToDo-Karten" cross-promo, author bio card, "Weiterlesen"
related-post card. Widths, fonts, and the Passend-dazu card's
border/padding/spacing were corrected against the actual built Figma
frame (page-blog-detail, node 4667:344, jCCZyh1DGwdjpv1wGge9To) via
get_design_context after a few visually-wrong guesses.
- RichText.tsx: new "quote" case renders Lexical's blockquote feature as
the "Merke dir:" pull-quote — label+underline+divider+Caveat lines,
using the real exported sparkle/underline assets, matching Figma's
actual (background-less) structure instead of a guessed bordered card.
- lib/payload.ts: getPostBySlug() for single-post fetches.
- lib/format.ts: formatDate() — "03. Juli 2025"-style German dates.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Replace both placeholder images with the actual exports pulled from
the built Figma page-404 (node 4692:341, file jCCZyh1DGwdjpv1wGge9To):
testimonial-photo (4699:372) at full 810x306 resolution, and the
sticky-note-404 (4693:382) — a real photographed/rendered note, not the
hand-coded CSS+Caveat approximation this had before.
- Help-link icon hover: subtle scale-110 zoom (matching Testimonials.tsx's
avatar hover) instead of a color inversion.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Swap the testimonial band's placeholder photo for one cropped directly
from the actual mockup pixels (mockups/einfach-produktiv_mockup_404.png)
instead of reusing an unrelated existing site asset.
- Remove the search bar — no search backend exists to wire it to, so it
was a dead decorative element.
- Add micro-interactions: main CTA arrow slides right on hover, sticky
note un-rotates on hover, help-link cards lift + icon circle inverts to
brand fill + arrow slides right on hover.
- Help-link CTAs ("Zur Startseite" etc.) now text-text-primary (black)
instead of text-brand.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Products now come from Payload's new "products" collection instead of a
hardcoded catalog, same pattern already used for blog posts:
- lib/payload.ts: getProducts()/getProductBySlug() (server-side fetch,
60s ISR)
- New /api/products route so client components (CartContent,
RelatedProducts) can reach the same data without a server-only import
- lib/products.ts: useProducts() hook replacing the old PRODUCTS record
- ProductGrid (/shop) fetches server-side directly; now shows all
catalog products except notizbuch-klarheit (matches Figma's 4-card
page-shop-overview — still cross-sold via RelatedProducts)
- ProductSpotlight and /todo-cards' Pricing now pull price/photo from
the same CMS product instead of a separately hardcoded "12,90 €", so
the two can't silently drift apart
- formatPrice moved to a new lib/format.ts (plain, no "use client") —
Server Components can't call functions exported from a "use client"
module directly, which lib/products.ts now is because of the hook
Also fixes two unrelated bugs surfaced along the way: the add-to-cart
button visibly resizing when its "Hinzugefügt ✓" success state showed
(fixed with a CSS-grid text stack sized to the wider of the two
strings), and removes the now-unused local product images from public/.
- New /shop overview, /cart (real cart state via useSyncExternalStore),
/versand (shipping policy page with TOC) and /newsletter detail page
- Cart: quantity/removal, order summary, related-products cross-sell
with randomized picks, VersandModal quick-reference instead of
navigating away, MwSt. disclosure next to unit prices
- Add-to-cart UX: inline success feedback (green state) plus a
fly-to-navbar-cart-icon animation (CartFlyProvider) with a delayed
badge count-up; AddToCartButton no longer navigates straight to /cart
- Shared lib/products.ts catalog and lib/shipping.ts constants (cost,
free-shipping threshold, handling/transit days) so cart, trust badges
and the versand page can never drift apart
- Fix Navbar smooth-scroll easing (ease-out instead of ease-in-out, no
more perceived start delay); compress newsletter modal photo
2.4MB -> 85KB to fix first-open jank
New /todo-cards page (Hero, How-it-works, Focus, Testimonials, Pricing)
built with the fluid clamp() token system (app/lib/fluid.ts) and
scroll-reveal animations (app/components/Reveal.tsx), matching styling
consistency with /challenge's testimonial section.
Navbar: page-aware active state and anchor-link navigation from any
route (not just "/"), fixed logo click to actually navigate instead of
silently rewriting the URL, fluid nav text size, custom hash-scroll
handling for cross-page anchor links.
Hero: responsive breakpoint fix for the text/image split at Tablet
widths, entrance animation for the brand's orange dot, removed a red
dot artifact from hero.png.
Also includes prior uncommitted work on About/Blog/Newsletter/Footer
and the cart lib (app/lib/cart.ts).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Figma exports the hero image as a PNG with alpha channel — the background
is already transparent. Switched from <img mix-blend-multiply> to a
background-image div (background-size: contain, right center) so the
transparent PNG blends seamlessly into the cream section background with
no visible edge. Background-image also scales better for responsive.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cream card (bg-[#f8f3ec], rounded-xl) inside section padding of 80px.
Left copy column has fixed w-[38.25rem] (612px) with icon (-rotate-4)
and Lora heading; right form column is flex-1 with email input +
orange submit button side by side, privacy note below. Input and button
share items-stretch so they align to equal height.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two-column layout: left column stacks serif statement above a row of
Caveat quote (flex-1) + 2px golden divider + author bio (shrink-0).
Signature image is absolute-positioned just below the three Caveat lines
(top: 6.44rem = 3 × 32px line-height). Right column is a full-height
overflow-hidden container with object-cover author photo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fine 1px #d9d9d9 border with rounded-xl on all cards. Featured card
uses overflow-hidden to clip thumbnail flush left; secondary cards give
each thumbnail its own rounded-xl so it sits neatly inside the py-2
padded wrapper. Arrow uses standard → instead of unsupported U+1F816.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>