From 3da8b753950d8597c2ab80744453757abcac9e5e Mon Sep 17 00:00:00 2001 From: Marco Date: Fri, 24 Jul 2026 18:48:18 +0000 Subject: [PATCH] Fix several mobile responsive issues across Hero, Newsletter, cart, and Challenge - Hero CTA: back to a single line below lg: (wrapping put the icon beside two lines and looked broken), sized down instead so the full phrase fits. - Hero heading: dropped the forced
after "darf" at true mobile widths, kept it only for the sm-lg tablet range it was added for. - Hero social proof: avatars+text now wrap and center instead of cramming onto one row (flex-wrap + justify-center, no fixed breakpoint needed). - Newsletter card icon: stacked above the copy and centered below md: instead of squeezed into a row beside it. - TrustRow: left-aligned below md: instead of centered (shop, cart, and every other page using this component). - Cart line item image: full width below sm: instead of a fixed 150px square. - Challenge EmailCapture (top + bottom CTA, same shared component): input and button stack full-width below sm: instead of squeezing into one row. - Challenge steps: icon above text and centered at every breakpoint (previously only from lg: up), connector arrows centered to match. --- app/cart/components/CartContent.tsx | 16 +++++++- app/challenge/components/EmailCapture.tsx | 8 +++- app/challenge/page.tsx | 14 +++++-- app/components/Hero.tsx | 45 ++++++++++++----------- app/components/Newsletter.tsx | 10 ++++- app/components/TrustRow.tsx | 2 +- 6 files changed, 64 insertions(+), 31 deletions(-) diff --git a/app/cart/components/CartContent.tsx b/app/cart/components/CartContent.tsx index 17e6bfd..1b6c28a 100644 --- a/app/cart/components/CartContent.tsx +++ b/app/cart/components/CartContent.tsx @@ -214,8 +214,20 @@ export function CartContent({
{i > 0 &&
}
-
- {product.name} + {/* Full-width on mobile (stacked layout) instead of the + fixed 150px square — a small square floating above + the text looked cramped on a narrow column that has + the width to spare; fixed 150px square again from + sm: once the row layout kicks in and the image sits + beside the text instead. */} +
+ {product.name} {discount !== null && ( -{discount}% diff --git a/app/challenge/components/EmailCapture.tsx b/app/challenge/components/EmailCapture.tsx index b45b31d..e00aff6 100644 --- a/app/challenge/components/EmailCapture.tsx +++ b/app/challenge/components/EmailCapture.tsx @@ -22,7 +22,13 @@ export function EmailCapture({ buttonLabel = "Challenge starten" }: { buttonLabe return (
-
+ {/* Stacked full-width below sm: — side by side, the button's own + content width plus the input's min-w-0 squeeze left it cramped + on a narrow phone. Default align-items: stretch in flex-col + mode is what makes both the input and the button (shrink-0, + fixed to its label's width) fill the row once stacked, no + explicit w-full needed on either. */} +
Jeden Tag ein Impuls. In nur wenigen Minuten.

- + {/* items-center below lg: (was items-start) — the step blocks + are centered columns now (see RevealItem below), so the + connector arrows between them need to be centered too, + not flush against the left edge. */} + {steps.flatMap((step, i) => [ - + // Icon-above-text, centered, at every breakpoint now + // (previously a left-aligned icon+text row below lg: — + // fixed 2026-07-24 to match the lg: layout instead of + // diverging from it). +
{step.icon}
-
+

{step.title}

{step.desc}

diff --git a/app/components/Hero.tsx b/app/components/Hero.tsx index 23b10a8..2748ffb 100644 --- a/app/components/Hero.tsx +++ b/app/components/Hero.tsx @@ -22,19 +22,19 @@ export function Hero() { viewport — this doubles as the page's entrance animation. */} - {/* Heading — forced break after "darf" below lg: (1024px), - natural wrap from lg: up. Below lg: the Hero is stacked - full-width and narrower per-viewport, where natural wrap - produced an awkward break — force it after "darf" there via - a responsive
(visible by default, turned off at lg:+). - From lg: up the 5/12 grid's text column wraps fine on its - own, no forced break needed. */} + {/* Heading — forced break after "darf" only in the sm-lg tablet + range (Hero stacked full-width, natural wrap there landed + awkwardly). Removed at true mobile widths (below sm:) 2026-07-24 + — narrower still, natural wrap there reads fine, and the + forced break made "darf" the whole first line, leaving very + little text above the CTA. Natural wrap from lg: up too, once + the 5/12 grid gives the column real width again. */}

- Produktivität darf
sich leicht anfühlen + Produktivität darf
sich leicht anfühlen
{/* Brand's signature orange dot (also in the logo/footer) — bouncy pop-in once the heading scrolls into view, timed to @@ -57,17 +57,14 @@ export function Hero() { href="/challenge" className="flex gap-4 items-center justify-center overflow-clip px-6 py-3 rounded-sm shrink-0 max-w-full bg-brand hover:brightness-95 active:scale-[0.97] transition-all" > - {/* whitespace-nowrap only from lg: up, where the 5-col text - column has room for the full phrase on one line. Below - lg: (stacked, narrower column) nowrap forced this button - wider than the column itself, overflowing on mobile — - fixed 2026-07-24 by letting it wrap to two lines instead - (leading-[2.375rem] was already sized for that). max-w-full - on the Link above is what actually makes the wrap happen — - without it, a flex item with items-start siblings just - grows to fit the unwrapped text instead of respecting the - column width. */} - + {/* Letting this wrap to two lines below lg: (tried 2026-07-24) + put the icon beside a two-line text block, which read as + broken rather than intentional. Smaller fixed size below + lg: instead, so the full phrase fits on one line within + the stacked mobile column's width — text-h3's own 19px + floor was still too wide for that at ~236px of available + text budget on a 375px phone. */} + Starte mit der 7-Tage-Challenge

@@ -75,8 +72,12 @@ export function Hero() {
- {/* Social proof */} -
+ {/* Social proof — flex-wrap + justify-center rather than a fixed + breakpoint: at narrow widths avatars+text don't fit on one + row, so the text wraps to its own line and both lines end up + centered; from lg: up (real column width) it still fits on + one row exactly as before, so nothing changes there. */} +
{/* Avatars — gap 2px, not overlapping */}
{["/avatar-1.jpg", "/avatar-2.jpg", "/avatar-3.jpg"].map((src, i) => ( @@ -89,7 +90,7 @@ export function Hero() {
))}
-

+

10.000+ Menschen vertrauen einfach-produktiv

diff --git a/app/components/Newsletter.tsx b/app/components/Newsletter.tsx index 331142f..6a7f7b7 100644 --- a/app/components/Newsletter.tsx +++ b/app/components/Newsletter.tsx @@ -46,8 +46,14 @@ export function Newsletter({ {/* Rounded card: cream bg, stacks below md */} - {/* Left: copy — fixed width from md+ so the form always gets the remaining space */} -
+ {/* Left: copy — fixed width from md+ so the form always gets the remaining space. + Icon+text stacked (icon on top, centered) below md: — side by + side they squeezed the text into a ~164px column on a 375px + phone (icon width + gap eating most of the card's inner + width), wrapping awkwardly. Row layout with the icon beside + the text is fine again from md+, where the fixed copy-column + width leaves real room. */} +
{/* Decorative envelope icon, tilted -4° as per design */}
diff --git a/app/components/TrustRow.tsx b/app/components/TrustRow.tsx index ce1da57..1c31e43 100644 --- a/app/components/TrustRow.tsx +++ b/app/components/TrustRow.tsx @@ -11,7 +11,7 @@ export async function TrustRow() { if (items.length === 0) return null; return ( -
+
{items.map((item, i) => (
{i > 0 &&
}