Fix more mobile responsive issues: Hero, arrows, cart button, checkmarks, modal
- Newsletter card icon: fixed an aspect-ratio distortion bug (w-16 maps to this project's fluid --spacing-16, which floors to 40px below 768px, paired with a fixed 55px height — squished the icon on mobile). Same root cause existed in NewsletterModal's envelope icon; that one's now just hidden below md: instead per feedback. - Hero: subtitle sized down and CTA checkmark icon scaled to match below lg:, social proof text always wraps below the avatars there instead of only when it doesn't fit. - Werkzeuge connector arrows (todo-cards/newsletter/challenge HowItWorks): object-contain added — the SVG has preserveAspectRatio="none" and was stretching to fill the square mobile box instead of keeping its thin-arrow shape. - Challenge bottom CTA: icon now stacks above the copy, centered, below lg: to match the Home Newsletter card's pattern. - Homepage Werkzeuge icons: smaller below md: to match the (fluid-floor) text size next to them. - Blog detail "Passend dazu" card: the fixed w-[19rem] title column plus "Entdecken" sharing its row overflowed on mobile; stacked below sm: instead, with a little top margin on "Entdecken". - Todo-Karten checklist checkmarks: recolored brand-orange (icon-check .svg's fill lives in an internal CSS var that can't be overridden from outside an <img>-loaded SVG, so switched to an inline SVG) and top-aligned instead of vertically centered. - AddToCartButton: added whitespace-nowrap to the stacked-label grid (used to reserve button width across all possible label texts) — one of those labels wrapping to two lines on a narrow w-full button was inflating the row height for whichever label is actually showing, leaving a tall empty gap under "Ausverkauft".
This commit is contained in:
@@ -128,7 +128,14 @@ export function AddToCartButton({
|
||||
also reserves space for "Ausverkauft"/"Maximale Menge im
|
||||
Warenkorb" — the widest of the four wins regardless of which is
|
||||
showing. */}
|
||||
<span className="relative grid">
|
||||
{/* whitespace-nowrap — inherited by every stacked span below. On a
|
||||
w-full button (e.g. this page's mobile layout), "Maximale Menge
|
||||
im Warenkorb" is long enough to wrap to two lines without this,
|
||||
and since every stacked span shares the same grid cell, that
|
||||
inflated the row height for whichever text is actually showing
|
||||
too — "Ausverkauft" rendered with a tall empty gap underneath it
|
||||
(fixed 2026-07-24). */}
|
||||
<span className="relative grid whitespace-nowrap">
|
||||
<span className="invisible [grid-area:1/1]" aria-hidden="true">
|
||||
{label}
|
||||
</span>
|
||||
|
||||
+13
-10
@@ -47,8 +47,10 @@ export function Hero() {
|
||||
</PopIn>
|
||||
</p>
|
||||
|
||||
{/* Subheading */}
|
||||
<p className="font-semibold leading-[2.375rem] min-w-full shrink-0 text-text-primary text-h-emphasis w-[min-content] [word-break:break-word] not-italic">
|
||||
{/* Subheading — smaller fixed size below lg:, text-h-emphasis's
|
||||
own 20px floor read too large next to the now-smaller mobile
|
||||
CTA text. leading shrinks to match, not just font-size. */}
|
||||
<p className="font-semibold leading-[1.75rem] lg:leading-[2.375rem] min-w-full shrink-0 text-text-primary text-[1rem] lg:text-h-emphasis w-[min-content] [word-break:break-word] not-italic">
|
||||
Für Menschen mit Familie, Verantwortung und zu wenig Zeit
|
||||
</p>
|
||||
|
||||
@@ -67,17 +69,18 @@ export function Hero() {
|
||||
<span className="font-semibold leading-[2.375rem] text-text-primary text-[0.8125rem] lg:text-h3 whitespace-nowrap not-italic">
|
||||
Starte mit der 7-Tage-Challenge
|
||||
</span>
|
||||
<div className="relative h-[1.1875rem] w-[1.5625rem] shrink-0">
|
||||
<Image alt="" src="/icon-check.svg" fill sizes="26px" />
|
||||
{/* Scaled down to match the smaller mobile CTA text (same
|
||||
~0.76 aspect ratio as the lg: size), full size again from
|
||||
lg: up alongside text-h3. */}
|
||||
<div className="relative h-[0.8125rem] w-[1.0625rem] lg:h-[1.1875rem] lg:w-[1.5625rem] shrink-0">
|
||||
<Image alt="" src="/icon-check.svg" fill sizes="(min-width: 1024px) 26px, 17px" />
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* 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. */}
|
||||
<div className="flex flex-wrap gap-3 items-center justify-center overflow-clip shrink-0 w-full">
|
||||
{/* Social proof — always avatars-then-text on two lines below
|
||||
lg: (not just when it happens to overflow), single row again
|
||||
from lg: up where the real column width fits it fine. */}
|
||||
<div className="flex flex-col lg:flex-row gap-3 items-center justify-center overflow-clip shrink-0 w-full">
|
||||
{/* Avatars — gap 2px, not overlapping */}
|
||||
<div className="flex gap-[0.125rem] items-center shrink-0">
|
||||
{["/avatar-1.jpg", "/avatar-2.jpg", "/avatar-3.jpg"].map((src, i) => (
|
||||
|
||||
@@ -55,7 +55,14 @@ export function Newsletter({
|
||||
width leaves real room. */}
|
||||
<div className="flex flex-col items-center gap-4 text-center w-full md:flex-row md:items-start md:gap-8 md:text-left md:w-[var(--newsletter-copy-width)] md:py-4 md:shrink-0">
|
||||
|
||||
{/* Decorative envelope icon, tilted -4° as per design */}
|
||||
{/* 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). */}
|
||||
<div className="flex items-center justify-center shrink-0 w-[4.23rem] h-[3.71rem]">
|
||||
<div className="-rotate-4 -scale-y-100">
|
||||
<Image
|
||||
@@ -63,7 +70,7 @@ export function Newsletter({
|
||||
src="/newsletter-icon.svg"
|
||||
width={64}
|
||||
height={55}
|
||||
className="w-16 h-[3.438rem] block"
|
||||
className="w-[4rem] h-[3.438rem] block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -172,8 +172,8 @@ export function NewsletterModal({ open, onClose }: { open: boolean; onClose: ()
|
||||
{/* -scale-y-100 is required, not just -rotate-4 — the SVG
|
||||
itself is authored upside-down (matches how Newsletter.tsx
|
||||
uses this exact same asset); without it the icon renders
|
||||
flipped. */}
|
||||
<div className="w-16 h-14 -rotate-4 -scale-y-100">
|
||||
flipped. Hidden below md: — removed on mobile 2026-07-24. */}
|
||||
<div className="hidden md:block w-16 h-14 -rotate-4 -scale-y-100">
|
||||
<Image alt="" src="/newsletter-icon.svg" width={64} height={56} className="w-full h-full" />
|
||||
</div>
|
||||
|
||||
|
||||
@@ -38,9 +38,13 @@ export async function Tools() {
|
||||
key={tool.id}
|
||||
className="md:col-span-4 flex gap-8 items-start rounded-md transition-transform duration-300 hover:-translate-y-1"
|
||||
>
|
||||
{/* Icon — uniform box, pre-flipped/rotated source asset */}
|
||||
<div className="relative flex items-center justify-center shrink-0 size-14">
|
||||
<Image alt="" src={tool.icon} fill sizes="56px" className="object-contain" />
|
||||
{/* Icon — uniform box, pre-flipped/rotated source asset.
|
||||
size-14 (56px) is a fixed value at every width (14 isn't
|
||||
one of this project's fluid spacing-scale steps) — smaller
|
||||
below md: so it doesn't dwarf the title/description text,
|
||||
which does shrink toward its own fluid floor there. */}
|
||||
<div className="relative flex items-center justify-center shrink-0 size-11 md:size-14">
|
||||
<Image alt="" src={tool.icon} fill sizes="(min-width: 768px) 56px, 44px" className="object-contain" />
|
||||
</div>
|
||||
|
||||
{/* Card content — self-stretch + h-full + justify-between so
|
||||
|
||||
Reference in New Issue
Block a user