The full-width bg-bg-muted band made the three categories read as
a disconnected banner, separate from the paragraph right above it
introducing them. Now inline in the same 48rem column as the rest
of the article — still icon-above-text with StepArrow connectors,
just not broken out into its own section anymore.
No numbers, no age/time data — just a clock silhouette (circle,
ticks, hands at 10:10). Every previous clock attempt tried to carry
actual data and kept going wrong; this one carries nothing, so
there's nothing to get wrong.
Went through several rounds (dot timeline, 24h dial, 12h dial,
decluttering) without landing right, and there's no way for me to
visually verify an SVG in this environment — kept guessing wrong.
Cutting it rather than continuing to iterate blind. The table stays
as the clear, working data source.
Too much straight paragraph text in a row. Trimmed nearly every
section by merging/shortening paragraphs, turned the "everything
competes for priority" list into a tag/pill row instead of prose,
and promoted the closing "Zufall/du entscheidest" line into a Quote
callout (matching the two others already on the page) instead of a
plain paragraph.
Lebensuhr clock: each of the 8 points had 3 stacked text lines (age,
time, vorm./nachm.) plus a leader line — too much text crammed
around a small dial. Down to just the age number per point; the
matching time is one glance away in the table.
3x3-system: removed the IconGrid3x3 decorative mark per explicit
feedback that it added nothing.
Category cards were a standalone 3-card grid with red/amber/green
accents (matching the original blog post) — out of step with how
every other icon-row on the site looks. Now the same icon-above-
text + StepArrow layout as /7-tage-klarheits-check's "So
funktioniert" and /lebensuhr's phase row, and the icons are a single
brand-orange line-icon style instead of per-category colors.
A clock face has 12 numbers, not 24 — the previous version invented
a 0-24 dial that doesn't exist on any real clock. Now a proper 1-12
face, with each age plotted at its 12h-mod position, labeled with
time + vorm./nachm. (every dial position is hit twice a day), and a
filled dot for vormittags vs. a hollow ring for nachmittags so the
two laps stay visually distinct.
Sized the SVG up (viewBox 250->420) after labels clipped at the
edge, and gave all 12 ticks a real 24h-scale number (0,2,4…22, full
"HH:00" at the 4 cardinal points) instead of just 00/06/12/18 — with
only 4 numbers shown at those same 4 positions, the dial read like
an ordinary 12-hour clock face (implying two laps/day) rather than
the single 24h lap it actually represents.
Category cards now break out into a full-width bg-bg-muted band
(same structural role as /lebensuhr's phase-row section), and the
page gets its own small decorative identity graphic — a literal 3x3
dot grid, paralleling that page's clock face.
The clock face only had age numbers — no way to tell which time on
the dial each one corresponded to. Added the matching time as a
second line under each age, and hour markers at 00/06/12/18 on the
ring itself so the dial reads as an actual 24h clock, not just an
abstract circle.
The four phases (Morgen/Vormittag/Nachmittag/Abend) had no explicit
tie back to age — readers had to infer it themselves from the clock
metaphor. Added an approximate age range per phase, using the same
age/90 = time/24 scale as the table (Vormittag ends exactly at 12:00
= age 45, which conveniently lines up with "Mittag").
/3x3-system:
- Categories now a 3-card grid (icon + colored top border) instead of
a plain bulleted list.
- Embeds the original blog post's Arbeit/Familie/Persönlich matrix
graphic, framed like the challenge page's image, with a caption
clarifying it's one example application (the surrounding text only
ever describes 3 categories, not a 3x3 grid).
- Closing CTA is now the same bordered-card link /lebensuhr uses.
- Tightened remaining prose.
/lebensuhr:
- Fixed missing side padding below 640px (the table card's
full-bleed negative-margin trick ate the page's own padding).
- Added a small decorative clock-face SVG above the table (8 ages
plotted at their proportional position) — company piece for the
table, which stays the actual data source.
The dot-on-a-line version dropped the explicit "Alter"/"Uhrzeit"
column labels, making it ambiguous which value was which, and
forced a horizontal scroll on mobile for no real gain. Back to an
actual <table> with headers, just dressed up: brand-underlined
header row, zebra striping, bg-bg-muted card frame.
A horizontal dotted line with each age/time pair on it reads as an
actual clock scale instead of a bare two-column table needing a
caption to explain itself. Same bg-bg-muted rounded-card treatment
already used by the AGB sidebar and the blog author box.
Reuses /7-tage-klarheits-check's StepArrow icon-row for the four life
phases (was plain H3 blocks), the checkmark-list pattern for the
closing three questions, and the blog's bordered "Passend dazu"
card treatment for the closing CTA. Also tightened the prose —
cut repeated points and filler transitions.
Adapted from the einfach-produktiv.com blog post — condensed and
tightened, same hand-styled article treatment as /lebensuhr since
this isn't CMS-backed content either. CTA links to
/7-tage-klarheits-check, matching that page's own closing link.
Content page about the "life clock" concept, ending with an internal
link to /7-tage-klarheits-check. Styled by hand (headings/quote match
RichText.tsx's converter output) since it's not CMS-backed content.
Renames the route, its canonical/OG metadata, Navbar's active-route
list, and the testimonials page filter to match. Also updates CTA
copy ("Klarheits-Check starten"), the "So funktioniert" heading, the
"3. Umsetzen" step text, and the breadcrumb label.
Side-by-side kicked in at sm (640px), squeezing the text column hard on
tablet widths. Moved the breakpoint to lg (1024px), matching the
secondary posts' grid below, which already used lg for the same reason.
The card's height was purely driven by the (short, fixed) text column's
content regardless of viewport width. lg:min-h-[26rem] gives it real
height on large screens; the image's sm:h-full and the text column's
justify-between both stretch to match.
Was full-bleed w-full with no cap, so on very wide screens the featured
card (and its now-h-full image column) kept stretching wider while the
image's height stayed pinned to the text column's content height —
increasingly squashed the wider the viewport got.
The 58%-wide image column at a hardcoded 220px tall produced a badly
elongated crop on wide viewports. sm:h-full lets the grid's natural
row-stretch (driven by the text column) size it instead, matching how
/blog's own featured card already does it.
Same breadcrumb/title/description block as every other page, no more
bespoke photo-bleed layout. Featured post card goes back to sitting
flush below the header (no more negative-margin overlap trick, which
only made sense with the photo's bottom edge to overlap).
Testimonials now pulled from Payload (page: "der-eine", same collection
as todo-cards/newsletter/challenge) instead of a hardcoded array. Pricing
adds a second, final buy CTA (same image+price+button card as the other
product pages' Pricing.tsx) for visitors who scroll past Hero's button.
PasstDazu moves to right before the Footer.
Focus.tsx icons now match the site's established icon-trust-*/icon-step-*
look (bold single-stroke outline, no circle badge) instead of the earlier
thin-stroke circled version. Hero.tsx's gallery now gets the same
horizontal page padding as the text column below lg:, and Focus.tsx's
body copy switches from centered to justified below md: to avoid ragged
centered multi-line text on small screens.
- PasstDazu.tsx now takes a productSlug prop and reads its cross-sell
target from the product's own relatedProduct field (Payload) instead
of hardcoding "todo-karten" — reusable on any product page now.
- payload.ts: Product/PayloadProduct gained relatedProduct, resolved via
a bounded-recursion mapPayloadProduct call (safe — the fetch's depth:2
means the nested relation's own relatedProduct is never populated).
- Focus.tsx icons: added the black stroked circle back around each glyph
(matches icon-step-3.png exactly) — dropped in the previous pass by
mistake while fixing the color/fill.
Bold uniform-weight black outline, no fill, no circle badge — same
language as tool-icon-todo-karten.png / icon-step-2.png / icon-step-3.png,
not the brand-orange circle-badge treatment tried previously.
- Removed the brand-story "Warum Der Eine.?" section entirely — for a
6,90€ accessory item its one unique fact (the two-sided engraving) was
already covered by Hero/Focus, the rest was pure narrative that didn't
aid the buying decision.
- Focus.tsx ("Was kann er?") widened to max-w-[75rem] (the site's
standard content width, same as Tools.tsx/HowItWorks.tsx) instead of
the narrower inset borrowed from HowItWorks' 3-item version.
- Icons switched from plain black line icons to a circle-badge + brand
orange (#f6a701) stroke treatment — matching the icon language already
used elsewhere on this page (IconCheck) and site (HowItWorks' own
stroked-circle step icon), the flat black icons read as a mismatched
style.
Same card shape as todo-cards/components/HowItWorks.tsx (icon on top,
centered, RevealGroup/RevealItem, identical typography) instead of the
inline-checkmark bullets tried first. Icons drawn from the der-eine.png
mockup's own icon row (pencil/sparkle/shield/pen line icons — no matching
/public asset existed for these concepts).
The full mockup-driven redesign (Banner/Lifestyle sections, restyled
Focus/Why/Pricing) was more than asked for — reverted back to the
pre-redesign version (Hero/Focus/Why exactly match commit 13fb37e), with
only the two changes actually requested applied on top:
- Focus.tsx ("Was kann er?"): dropped the product photo, plain text
section now — a second product shot here was redundant with Hero's own.
- Pricing.tsx (bottom price/buy bar) replaced by PasstDazu.tsx, a
"Passt dazu" cross-sell card linking to ToDo-Karten — same markup as
blog/[slug]/page.tsx's own related-product card, hardcoded to
"todo-karten" the same way Hero.tsx hardcodes "stift-kugelschreiber".
Kept the Payload product.image/gallery repointed at the mockup-derived
photos (ids 88/89) rather than reverting those too — the previous gallery
was mismatched stock photos of a different-colored pen, an independent
correction from the layout redesign.
Sections rebuilt to match der-eine.png (hero, tagline banner, brand-story
+ feature icons, lifestyle photo, final CTA bar with trust badges), but
each piece is built from patterns that already exist elsewhere on the
site rather than one-off layouts:
- Focus.tsx (feature icons) mirrors todo-cards/HowItWorks.tsx's exact
icon-top/title/desc card shape and typography
- Why.tsx (brand story) mirrors todo-cards/Focus.tsx's photo+text layout
- Pricing.tsx's trust-badge row reuses getCartTrustBadges() (real,
already-vetted copy) with /cart's own markup, not invented text
- Banner.tsx reuses --font-caveat and /icon-separator-right.svg (both
already used in Divider.tsx) instead of introducing new assets
Photos: product.image/gallery repointed (via direct DB write, see
reference_payload_direct_db_access) to two new Payload media docs
cropped directly from the mockup — the previous gallery was mismatched
supplier stock photos of a different-colored pen. Lifestyle.tsx's
desk photo is a static /public asset (page decoration showing the pen
next to another product, not a photo of the pen alone, so it doesn't
belong in Products.gallery).
Products.spotlightText switches from a plain textarea to a richText field
(Lexical, same default editor as every other richText field here) so
admins get a formatting toolbar. Rendered via a small dedicated inline
converter (bold + paragraphs only) rather than the full block-oriented
RichText.tsx, which is styled for article-length content (blog posts,
legal pages) and would add heading/paragraph spacing this teaser doesn't
want.
New copy throughout (hero, "Was kann er?", the "Warum Der Eine.?" brand-story
section replacing the old phone-vs-pen scenario grid, final CTA) plus the
Payload product's name/detailHref updated to match (done directly via psql,
no Payload admin API key available — see reference_payload_direct_db_access).
A static short link — e.g. printed on a QR code — that resolves to a
Payload-editable internal target path, so the link itself never needs
reprinting when the underlying content moves. Tracks a click count.
Long category names no longer force horizontal overflow — the row
wraps to a second line instead, with each segment kept from breaking
mid-word via whitespace-nowrap.
/der-alltagsstift mirrors the todo-cards pattern (Hero/HowItWorks/
Focus/Pricing) — renamed from "Der Eine" for brand-tonality reasons,
copy grounded in visually-verified product facts only.
/tasse-die-pause is a deliberately minimal Hero+Pricing scaffold —
naming/design concept for that product is still undecided, so the
headline reads product.name live from Payload instead of a hardcoded
tagline.
Image sits as a sibling to the badge/WishlistButton overlays, not
wrapping them — nested interactive elements would be invalid HTML and
would fire navigation on a wishlist click.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Cart line items had their own separate markup from ProductCard.tsx and
never got the title-link treatment — same product.href check, only
rendered as a link when the product actually has a detail page.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
README had fallen behind several recent changes: the shared ProductCard
component (was still describing three independently-duplicated grids),
ProductGallery's touch-swipe support, legal-pages' contentPart2 field
and company-settings-sourced name/address/email, shipping-methods as
the real cost/threshold source (lib/shipping.ts's old hardcoded
constants were deleted), and NotifyMeForm's single-row redesign.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
py-3 alone didn't match AddToCartInlineButton's real height — that
button's tallest child is its 1.875rem cart-icon image, not its text,
so an input with the same padding but only text content still rendered
shorter. Explicit h-14 matches the button's actual 56px.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
NotifyMeForm's single-row redesign matched AddToCartInlineButton's
button height exactly, which made the sold-out card's earlier
low-stock-line omission overcorrect — it ended up shorter than its
siblings instead of taller. Keeping that line unconditional (like every
other card) is what actually lines them up. Also swapped the generic
"E-Mail-Adresse" placeholder for one that states the purpose.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
NotifyMeForm was two stacked rows (email input + full-width button),
making an out-of-stock ProductCard taller than its in-stock siblings.
Redesigned as a single input with the submit control embedded inside it
(same py-3 as AddToCartInlineButton's own button, so the row height
matches exactly), and ProductCard now skips its reserved-height
low-stock line entirely for a fully-out-of-stock product, since that
line can never apply there.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- AGB: name/address/email now come from company-settings via new
VertragspartnerBlock (mid-document, see LegalPages.ts's contentPart2).
- VersandSections/VersandModal/CartContent/CheckoutContent/versand page:
shipping cost and free-shipping threshold now come from the real
ShippingMethods data (already fetched elsewhere for checkout), not the
hardcoded lib/shipping.ts constants — those had already drifted from
the real Payload values once. lib/shipping.ts deleted, nothing left to
export.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- ProductGallery: touch swipe (left/right) now navigates slides on mobile,
previously click-only.
- New shared ProductCard component used by ProductGrid/RelatedProducts/
MerklisteGrid — product title is now the card's link (replaces the
separate "Mehr erfahren" line), consistent aspect ratio across all
three grids, more compact cards.
- Datenschutz: name/address/email now come from company-settings via a
new VerantwortlicherBlock, same single-source pattern as Impressum's
AnbieterAngaben — no more hand-typed address to keep in sync.
- layout.tsx: render googleSearchConsoleVerification via Next's native
verification.google metadata field.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>