fix stacking cards: flatMap siblings, no wrappers, no shadow, z < header

ROOT CAUSE: each card was wrapped in its own div (min-h-[85vh]),
scoping sticky to that wrapper — cards could NEVER overlap.

FIX: flatMap returns all sticky divs + h-4 spacers as direct
siblings under the same parent (mt-14). Sticky now works
correctly — each card overlaps the previous with 20px peek.

- Removed all shadows (border-gray-100 only)
- z-index: 1-4 (was 10-40, conflicting with nav z-40)
- top: 72/92/112/132px (20px stagger)
- h-4 spacers between cards (no big white gaps)
- Regenerated dinner image: dark navy table, candlelight, £5,000
  pledge card — zero white space (was white tablecloth)
This commit is contained in:
2026-03-03 23:29:26 +08:00
parent dc1253af33
commit 6b71fa227b
19 changed files with 305 additions and 474 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 86 KiB

View File

@@ -157,61 +157,57 @@ export default function HomePage() {
We built the missing system between &ldquo;I&apos;ll donate&rdquo; and the money arriving.
</p>
{/* Stacking cards — sticky scroll effect */}
{/* Stacking cards — all sticky siblings in ONE parent */}
<div className="mt-14">
{PERSONAS.map((p, i) => {
{PERSONAS.flatMap((p, i) => {
const imgFirst = i % 2 === 0
return (
<div key={p.slug} className={i < PERSONAS.length - 1 ? "pb-36" : ""}>
<div
className="sticky will-change-transform"
style={{ top: `${72 + i * 16}px`, zIndex: 10 + i * 10 }}
const els = [
<div
key={p.slug}
className="sticky will-change-transform"
style={{ top: `${72 + i * 20}px`, zIndex: i + 1 }}
>
<Link
href={`/for/${p.slug}`}
className="group block bg-white border border-gray-100 overflow-hidden"
>
<Link
href={`/for/${p.slug}`}
className="group block bg-white shadow-[0_2px_8px_rgba(0,0,0,0.08)] overflow-hidden"
>
<div className={`flex flex-col ${imgFirst ? "md:flex-row" : "md:flex-row-reverse"}`}>
{/* Image — ~58%, fills full card height */}
<div className="md:w-7/12 relative overflow-hidden min-h-[220px] md:min-h-[400px]">
<Image
src={p.image}
alt={p.scenario}
fill
className="object-cover"
sizes="(max-width: 768px) 100vw, 58vw"
/>
</div>
{/* Text — ~42% */}
<div className="md:w-5/12 p-8 md:p-12 lg:p-14 flex flex-col justify-center">
<h3 className="text-lg md:text-xl font-black text-gray-900 group-hover:text-promise-blue transition-colors">
{p.scenario}
</h3>
{/* Pain stats */}
<div className="mt-5 space-y-1">
<p className="text-xl md:text-2xl lg:text-3xl font-black text-gray-400 tracking-tight leading-tight">
{p.stat1}
</p>
<p className="text-xl md:text-2xl lg:text-3xl font-black text-gray-900 tracking-tight leading-tight">
{p.stat2}
</p>
</div>
<p className="text-sm text-gray-500 leading-relaxed mt-5">
{p.copy}
</p>
<p className="text-xs font-semibold text-promise-blue mt-6 group-hover:underline">
{p.cta} &rarr;
</p>
</div>
<div className={`flex flex-col ${imgFirst ? "md:flex-row" : "md:flex-row-reverse"}`}>
<div className="md:w-7/12 relative overflow-hidden min-h-[220px] md:min-h-[400px]">
<Image
src={p.image}
alt={p.scenario}
fill
className="object-cover"
sizes="(max-width: 768px) 100vw, 58vw"
/>
</div>
</Link>
</div>
</div>
)
<div className="md:w-5/12 p-8 md:p-12 lg:p-14 flex flex-col justify-center">
<h3 className="text-lg md:text-xl font-black text-gray-900 group-hover:text-promise-blue transition-colors">
{p.scenario}
</h3>
<div className="mt-5 space-y-1">
<p className="text-xl md:text-2xl lg:text-3xl font-black text-gray-400 tracking-tight leading-tight">
{p.stat1}
</p>
<p className="text-xl md:text-2xl lg:text-3xl font-black text-gray-900 tracking-tight leading-tight">
{p.stat2}
</p>
</div>
<p className="text-sm text-gray-500 leading-relaxed mt-5">
{p.copy}
</p>
<p className="text-xs font-semibold text-promise-blue mt-6 group-hover:underline">
{p.cta} &rarr;
</p>
</div>
</div>
</Link>
</div>,
]
if (i < PERSONAS.length - 1) {
els.push(<div key={`sp-${i}`} className="h-4" aria-hidden="true" />)
}
return els
})}
</div>
</div>