feat: full responsive layout — mobile-first, lg breakpoint, fluid typography

Strategy: one layout breakpoint at lg (1024px), clamp() for fluid type.

Navbar: hamburger menu (animated ✕) with max-h dropdown, resize-close,
  h-20 mobile / h-[6.25rem] desktop, blur triggers on scroll or menu-open.
Hero: flex-col→lg:flex-row, clamp(2rem,5vw,4rem) heading, background-image
  scales responsively, gradient mask via .hero-mask only at lg+ in CSS.
Divider: flex-wrap + gap-y for smaller screens.
Tools: grid-cols-1→md:2→lg:3, removed fixed height and per-card paddingRight.
Blog: featured flex-col→lg:flex-row, secondary flex-col→md:flex-row,
  excerpt hidden on mobile secondary cards to save space.
About: flex-col→lg:flex-row, clamp on quote size, min-h-[18rem] for photo.
Newsletter: flex-col→lg:flex-row, input+button stack on xs / row on sm+.
Footer: flex-col→lg:flex-row, flex-wrap on legal links.
globals.css: scroll-padding-top 5rem mobile / 6.25rem desktop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marco
2026-06-30 22:04:23 +00:00
parent ed575d5aa0
commit 2505a87717
9 changed files with 222 additions and 172 deletions
+15 -16
View File
@@ -1,32 +1,31 @@
export function About() {
return (
<section id="ueber-bjoern" className="bg-[#111] flex items-stretch w-full">
<section id="ueber-bjoern" className="bg-[#111] flex flex-col lg:flex-row items-stretch w-full">
{/* Left: text content — flex-[1_0_0] = flex: 1 0 0, no shrink, exactly 50% */}
<div className="flex-[1_0_0] flex flex-col gap-4 justify-center px-[5rem] py-8 min-w-0">
{/* Left: text content */}
<div className="flex-[1_0_0] flex flex-col gap-4 justify-center px-4 md:px-8 lg:px-[5rem] py-10 lg:py-8 min-w-0">
{/* Large serif statement — width-constrained as per design */}
{/* Large serif statement */}
<p
className="font-semibold text-white text-[1.75rem] leading-normal w-[17.625rem]"
style={{ fontFamily: "var(--font-lora)" }}
className="font-semibold text-white leading-normal"
style={{ fontFamily: "var(--font-lora)", fontSize: "clamp(1.375rem, 2.5vw, 1.75rem)", maxWidth: "17.625rem" }}
>
Ich glaube nicht, dass Menschen mehr Disziplin brauchen.
</p>
{/* Quote row: script quote + golden divider + author bio */}
<div className="flex items-start justify-between w-full">
<div className="flex items-start justify-between w-full gap-4">
{/* Caveat script text with signature positioned below */}
{/* Caveat script text with signature */}
<div className="relative flex-1" style={{ minHeight: "8rem" }}>
<div
className="font-normal text-[#f6a701] text-[2.25rem]"
style={{ fontFamily: "var(--font-caveat)", lineHeight: "2rem" }}
className="font-normal text-[#f6a701]"
style={{ fontFamily: "var(--font-caveat)", fontSize: "clamp(1.75rem, 3vw, 2.25rem)", lineHeight: "2rem" }}
>
<p>Ich glaube,</p>
<p>sie brauchen&nbsp;</p>
<p>weniger Reibung.</p>
</div>
{/* Signature — absolute, sits just below the three Caveat lines (3 × 32px = 96px) */}
<div
className="absolute overflow-hidden pointer-events-none"
style={{ top: "6.44rem", left: "1.5rem", width: "9.375rem", height: "1.375rem" }}
@@ -40,12 +39,12 @@ export function About() {
</div>
</div>
{/* Golden vertical divider + author lines */}
<div className="flex gap-6 items-start shrink-0">
{/* Golden divider + author */}
<div className="flex gap-4 lg:gap-6 items-start shrink-0">
<div className="bg-[#f6a701] w-[2px] h-24 shrink-0" />
<div
className="text-white font-normal whitespace-nowrap"
style={{ fontSize: "1rem", lineHeight: "1.5rem" }}
style={{ fontSize: "clamp(0.875rem, 1.5vw, 1rem)", lineHeight: "1.5rem" }}
>
<p>Björn.</p>
<p>Führungskraft.</p>
@@ -57,8 +56,8 @@ export function About() {
</div>
</div>
{/* Right: author photo — flex-[1_0_0] keeps it at exactly 50% */}
<div className="flex-[1_0_0] relative overflow-hidden" style={{ minHeight: "14rem" }}>
{/* Right: author photo */}
<div className="flex-[1_0_0] relative overflow-hidden" style={{ minHeight: "18rem" }}>
<img
alt="Björn"
src="/about-author.jpg"
+24 -25
View File
@@ -33,44 +33,44 @@ const secondary = [
export function Blog() {
return (
<div id="blog" className="flex flex-col gap-[3rem] items-start pb-[4rem] w-full bg-[#f5f0e8]">
<div id="blog" className="flex flex-col gap-8 lg:gap-[3rem] items-start pb-10 lg:pb-[4rem] w-full bg-[#f5f0e8]">
{/* Section header */}
<div className="flex flex-col gap-[0.5rem] items-start px-[5rem] w-full">
<div className="flex flex-col gap-2 items-start px-4 md:px-8 lg:px-[5rem] w-full">
<p className="font-bold text-[#f6a701] text-[1.25rem]">
Neue Impulse
</p>
<p
className="font-semibold text-[#222221] text-[1.75rem] leading-normal"
style={{ fontFamily: "var(--font-lora)" }}
className="font-semibold text-[#222221] leading-normal"
style={{ fontFamily: "var(--font-lora)", fontSize: "clamp(1.375rem, 2.5vw, 1.75rem)" }}
>
Gedanken, Methoden &amp; Impulse
</p>
</div>
{/* Posts grid */}
<div className="flex flex-col gap-[2.5rem] items-start px-[5rem] w-full">
<div className="flex flex-col gap-4 lg:gap-[2.5rem] items-start px-4 md:px-8 lg:px-[5rem] w-full">
{/* Featured post — thumbnail flush left, card clips with overflow-hidden */}
<div className="w-full border border-[#d9d9d9] rounded-xl overflow-hidden flex gap-3">
<div className="relative h-[220px] shrink-0 w-[60%]">
{/* Featured post: stacked on mobile, side-by-side on lg+ */}
<div className="w-full border border-[#d9d9d9] rounded-xl overflow-hidden flex flex-col lg:flex-row lg:gap-3">
<div className="relative h-[200px] md:h-[240px] lg:h-[220px] w-full lg:w-[60%] lg:shrink-0">
<img
alt=""
src={featured.thumbnail}
className="absolute inset-0 w-full h-full object-cover pointer-events-none"
/>
</div>
<div className="flex flex-1 flex-col justify-between py-4 pr-4 min-w-0">
<div className="flex flex-1 flex-col justify-between p-4 lg:py-4 lg:pr-4 lg:pl-0 min-w-0">
<div className="flex flex-col gap-3">
<div className="flex gap-2 items-center font-semibold text-[#777] text-[1rem] uppercase whitespace-nowrap">
<div className="flex gap-2 items-center font-semibold text-[#777] text-[0.875rem] uppercase whitespace-nowrap">
<span>{featured.category}</span>
<span></span>
<span>{featured.readTime}</span>
</div>
<div className="flex flex-col gap-4 text-[#222221]">
<div className="flex flex-col gap-3 text-[#222221]">
<p
className="font-semibold text-[1.75rem] leading-normal"
style={{ fontFamily: "var(--font-lora)" }}
className="font-semibold leading-normal"
style={{ fontFamily: "var(--font-lora)", fontSize: "clamp(1.25rem, 2vw, 1.75rem)" }}
>
{featured.title}
</p>
@@ -81,22 +81,21 @@ export function Blog() {
</div>
<Link
href={featured.href}
className="font-bold text-[1rem] text-[#222221] whitespace-nowrap hover:text-[#f6a701] transition-colors"
className="font-bold text-[1rem] text-[#222221] whitespace-nowrap hover:text-[#f6a701] transition-colors mt-4 lg:mt-0"
>
Zum Beitrag
</Link>
</div>
</div>
{/* Secondary posts — thumbnail with own rounded-xl, card py-2 only */}
<div className="flex gap-3 w-full">
{/* Secondary posts: 1-col mobile → 2-col md+ */}
<div className="flex flex-col md:flex-row gap-4 lg:gap-3 w-full">
{secondary.map((post) => (
<div
key={post.title}
className="flex-1 border border-[#d9d9d9] rounded-xl flex gap-3 h-[230px] items-center py-2"
className="flex-1 border border-[#d9d9d9] rounded-xl flex gap-3 items-center py-2"
>
{/* Thumbnail: own border-radius so it sits neatly inside the padded card */}
<div className="rounded-xl overflow-hidden shrink-0 h-full w-[14.7rem]">
<div className="rounded-xl overflow-hidden shrink-0 h-[120px] w-[9rem] md:h-[160px] md:w-[12rem] lg:h-[calc(230px-1rem)] lg:w-[14.7rem]">
<img
alt=""
src={post.thumbnail}
@@ -104,27 +103,27 @@ export function Blog() {
/>
</div>
<div className="flex flex-1 flex-col justify-between h-full min-w-0 py-2 pr-2 text-[#222221]">
<div className="flex flex-col gap-3">
<div className="flex gap-2 items-center font-semibold text-[#777] text-[1rem] uppercase whitespace-nowrap">
<div className="flex flex-col gap-2 lg:gap-3">
<div className="flex gap-2 items-center font-semibold text-[#777] text-[0.8rem] lg:text-[1rem] uppercase whitespace-nowrap">
<span>{post.category}</span>
<span></span>
<span>{post.readTime}</span>
</div>
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-2 lg:gap-4">
<p
className="font-semibold text-[1.25rem] leading-normal"
className="font-semibold leading-normal text-[1.1rem] lg:text-[1.25rem]"
style={{ fontFamily: "var(--font-lora)" }}
>
{post.title}
</p>
<p className="font-normal text-[1rem] leading-6">
<p className="font-normal text-[0.9rem] lg:text-[1rem] leading-6 hidden md:block">
{post.excerpt}
</p>
</div>
</div>
<Link
href={post.href}
className="font-bold text-[1rem] whitespace-nowrap hover:text-[#f6a701] transition-colors"
className="font-bold text-[0.9rem] lg:text-[1rem] whitespace-nowrap hover:text-[#f6a701] transition-colors mt-2"
>
Zum Beitrag
</Link>
+2 -2
View File
@@ -1,7 +1,7 @@
export function Divider() {
return (
<div className="flex items-center justify-center pb-[1.25rem] pt-[3rem] w-full bg-[#f5f0e8]">
<div className="flex gap-[2rem] items-center overflow-clip shrink-0">
<div className="flex items-center justify-center pb-[1.25rem] pt-8 lg:pt-[3rem] w-full bg-[#f5f0e8]">
<div className="flex flex-wrap gap-x-[2rem] gap-y-3 items-center justify-center px-4">
<p
className="font-bold leading-normal text-[#222221] text-[2rem] whitespace-nowrap"
+9 -11
View File
@@ -9,18 +9,16 @@ const links = [
export function Footer() {
return (
<footer className="bg-[#111] flex flex-col items-center justify-end w-full mt-auto">
<footer className="bg-[#111] flex flex-col items-center w-full mt-auto">
{/* 3px top divider — #30302c, not a border */}
{/* 3px top divider */}
<div className="bg-[#30302c] h-[3px] w-full shrink-0" />
{/* Footer inner — max-width 1280px, centered */}
{/* Footer inner */}
<div className="flex flex-col items-start w-full max-w-[1280px] py-4">
<div className="flex flex-col lg:flex-row items-start lg:items-center justify-between gap-5 lg:gap-0 px-4 md:px-8 lg:px-16 w-full">
{/* Three columns: logo | @handle | links */}
<div className="flex items-center justify-between px-16 w-full">
{/* Logo: "einfach produktiv" white + "." gold */}
{/* Logo */}
<div className="flex items-center p-2 shrink-0">
<span
className="font-semibold text-white text-[1.25rem] leading-normal whitespace-nowrap"
@@ -31,16 +29,16 @@ export function Footer() {
</span>
</div>
{/* Social handle — Lora Regular (weight 400), 24px */}
{/* Social handle */}
<p
className="font-normal text-white text-[1.5rem] text-center leading-[1.2] whitespace-nowrap shrink-0"
className="font-normal text-white text-[1.25rem] lg:text-[1.5rem] lg:text-center leading-[1.2] whitespace-nowrap shrink-0"
style={{ fontFamily: "var(--font-lora)", fontWeight: 400 }}
>
@einfach.produktiv
</p>
{/* Legal links — Inter Regular 14px, gap 24px */}
<div className="flex items-start gap-6 shrink-0">
{/* Legal links */}
<div className="flex flex-wrap items-start gap-x-6 gap-y-2 shrink-0">
{links.map((link) => (
<Link
key={link.label}
+21 -32
View File
@@ -3,75 +3,64 @@ import Image from "next/image";
export function Hero() {
return (
<section className="bg-[#f5f0e8] flex items-center justify-between relative w-full overflow-hidden">
<section className="bg-[#f5f0e8] flex flex-col lg:flex-row items-center justify-between w-full overflow-hidden">
{/* Left: text content */}
<div className="flex flex-[1_0_0] flex-col gap-[1.75rem] items-start min-w-px overflow-clip pl-[5rem] pr-[2.5rem] relative">
<div className="flex flex-col gap-6 lg:gap-[1.75rem] items-start w-full lg:flex-[1_0_0] lg:min-w-px px-4 md:px-8 lg:pl-[5rem] lg:pr-[2.5rem] pt-10 pb-8 lg:py-0">
{/* Heading — w-[min-content] forces wrap at widest word ("Produktivität") */}
{/* Heading — fluid size: 2rem mobile → 4rem desktop */}
<p
className="font-semibold leading-[0] min-w-full shrink-0 text-[0px] text-black w-[min-content] [word-break:break-word]"
style={{ fontFamily: "var(--font-playfair)" }}
className="font-semibold leading-[1.1] text-black w-full [word-break:break-word]"
style={{ fontFamily: "var(--font-playfair)", fontSize: "clamp(2rem, 5vw, 4rem)" }}
>
<span className="leading-[4.5rem] text-[4rem]">Produktivität darf sich leicht anfühlen</span>
<span className="leading-[4.5rem] text-[4rem] text-[#fdb705]">.</span>
<span>Produktivität darf sich leicht anfühlen</span>
<span style={{ color: "#fdb705" }}>.</span>
</p>
{/* Subheading */}
<p className="font-semibold leading-[2.375rem] min-w-full shrink-0 text-[#222221] text-[1.5rem] w-[min-content] [word-break:break-word] not-italic">
{/* Subheading — fluid: 1.125rem → 1.5rem */}
<p
className="font-semibold text-[#222221] w-full [word-break:break-word]"
style={{ fontSize: "clamp(1.125rem, 2vw, 1.5rem)", lineHeight: "1.4" }}
>
Für Menschen mit Familie, Verantwortung und zu wenig Zeit
</p>
{/* CTA */}
<Link
href="/challenge"
className="flex gap-[1rem] items-center justify-center overflow-clip px-[1.5rem] py-[0.75rem] rounded-[0.5rem] shrink-0 bg-[#f6a701] hover:brightness-95 transition-all"
className="flex gap-4 items-center justify-center overflow-hidden px-6 py-3 rounded-lg shrink-0 bg-[#f6a701] hover:brightness-95 transition-all"
>
<span className="font-semibold leading-[2.375rem] text-[#222221] text-[1.375rem] whitespace-nowrap not-italic">
<span className="font-semibold text-[#222221] text-[1.125rem] lg:text-[1.375rem] whitespace-nowrap">
Starte mit der 7-Tage-Challenge
</span>
<div className="relative h-[1.1875rem] w-[1.5625rem] shrink-0">
<img
alt=""
src="/icon-check.svg"
className="absolute inset-0 w-full h-full"
/>
<img alt="" src="/icon-check.svg" className="absolute inset-0 w-full h-full" />
</div>
</Link>
{/* Social proof */}
<div className="flex gap-[0.75rem] items-start overflow-clip shrink-0 w-full">
{/* Avatars — gap 2px, not overlapping */}
<div className="flex gap-[0.125rem] items-center shrink-0">
<div className="flex gap-3 items-center shrink-0 w-full">
<div className="flex gap-0.5 items-center shrink-0">
{["/avatar-1.jpg", "/avatar-2.jpg", "/avatar-3.jpg"].map((src, i) => (
<div
key={i}
className="relative w-[2.8125rem] h-[2.8125rem] rounded-full overflow-hidden shrink-0"
>
<div key={i} className="relative w-10 h-10 lg:w-[2.8125rem] lg:h-[2.8125rem] rounded-full overflow-hidden shrink-0">
<Image src={src} alt="" fill className="object-cover" />
</div>
))}
</div>
<p className="flex-[1_0_0] font-normal leading-[1.5rem] text-[#222221] text-[1rem] [word-break:break-word]">
<p className="font-normal leading-6 text-[#222221] text-[0.9rem] lg:text-[1rem] [word-break:break-word]">
10.000+ Menschen vertrauen einfach-produktiv
</p>
</div>
</div>
{/* Right: hero image — gradient mask fades left + top edges into the cream background */}
{/* Right: hero image — full width on mobile, fixed column on desktop */}
<div
className="h-[36.4375rem] shrink-0 w-[55.4375rem]"
className="hero-mask w-full h-[260px] md:h-[340px] lg:h-[36.4375rem] lg:shrink-0 lg:w-[55.4375rem]"
style={{
backgroundImage: "url('/hero.png')",
backgroundSize: "cover",
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
WebkitMaskImage:
"linear-gradient(to right, transparent 0%, black 14%), linear-gradient(to bottom, transparent 0%, black 10%)",
WebkitMaskComposite: "destination-in",
maskImage:
"linear-gradient(to right, transparent 0%, black 14%), linear-gradient(to bottom, transparent 0%, black 10%)",
maskComposite: "intersect",
}}
aria-hidden="true"
/>
+93 -27
View File
@@ -4,8 +4,7 @@ import { useEffect, useState } from "react";
import Link from "next/link";
import Image from "next/image";
const NAVBAR_HEIGHT = 100; // px — matches h-[6.25rem]
const SCROLL_DURATION = 800; // ms
const SCROLL_DURATION = 800;
function smoothScrollTo(targetY: number) {
const startY = window.scrollY;
@@ -15,10 +14,10 @@ function smoothScrollTo(targetY: number) {
function step(now: number) {
const elapsed = now - startTime;
const progress = Math.min(elapsed / SCROLL_DURATION, 1);
// ease-in-out cubic
const ease = progress < 0.5
? 4 * progress ** 3
: 1 - (-2 * progress + 2) ** 3 / 2;
const ease =
progress < 0.5
? 4 * progress ** 3
: 1 - (-2 * progress + 2) ** 3 / 2;
window.scrollTo(0, startY + distance * ease);
if (progress < 1) requestAnimationFrame(step);
}
@@ -35,6 +34,7 @@ const navLinks = [
export function Navbar() {
const [scrolled, setScrolled] = useState(false);
const [menuOpen, setMenuOpen] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 8);
@@ -42,17 +42,34 @@ export function Navbar() {
return () => window.removeEventListener("scroll", onScroll);
}, []);
// Close mobile menu on resize to desktop
useEffect(() => {
const onResize = () => { if (window.innerWidth >= 1024) setMenuOpen(false); };
window.addEventListener("resize", onResize);
return () => window.removeEventListener("resize", onResize);
}, []);
const handleAnchorClick = (e: React.MouseEvent<HTMLAnchorElement>, href: string) => {
e.preventDefault();
setMenuOpen(false);
const navH = window.innerWidth >= 1024 ? 100 : 80; // desktop / mobile navbar px
const el = document.getElementById(href.slice(1));
if (el) smoothScrollTo(el.getBoundingClientRect().top + window.scrollY - navH);
history.replaceState(null, "", href);
};
const blurred = scrolled || menuOpen;
return (
<header
className={`sticky top-0 z-50 w-full h-[6.25rem] flex items-center px-[2rem] transition-[background-color,backdrop-filter] duration-300 ${
scrolled
? "bg-[#f5f0e8]/80 backdrop-blur-md"
: "bg-[#f5f0e8]"
className={`sticky top-0 z-50 w-full flex flex-col transition-[background-color,backdrop-filter] duration-300 ${
blurred ? "bg-[#f5f0e8]/90 backdrop-blur-md" : "bg-[#f5f0e8]"
}`}
>
<div className="w-full flex items-center justify-between">
{/* Main bar */}
<div className="h-20 lg:h-[6.25rem] flex items-center justify-between px-4 lg:px-8">
{/* Logo — exported directly from Figma */}
{/* Logo */}
<Link href="/" className="shrink-0">
<Image
src="/logo.png"
@@ -60,25 +77,18 @@ export function Navbar() {
width={181}
height={61}
priority
className="w-[130px] lg:w-[181px] h-auto"
/>
</Link>
{/* Nav links */}
<nav className="flex items-center gap-[3rem]">
{/* Desktop nav */}
<nav className="hidden lg:flex items-center gap-[3rem]">
{navLinks.map((link) =>
link.href.startsWith("#") ? (
<a
key={link.href}
href={link.href}
onClick={(e) => {
e.preventDefault();
const el = document.getElementById(link.href.slice(1));
if (el) {
const top = el.getBoundingClientRect().top + window.scrollY - NAVBAR_HEIGHT;
smoothScrollTo(top);
}
history.replaceState(null, "", link.href);
}}
onClick={(e) => handleAnchorClick(e, link.href)}
className="text-[1.125rem] font-semibold text-[#222221] tracking-[0.01125rem] hover:text-[#f6a701] transition-colors cursor-pointer"
>
{link.label}
@@ -95,22 +105,78 @@ export function Navbar() {
)}
</nav>
{/* CTA buttons */}
<div className="flex items-center gap-[0.75rem] p-[0.5rem]">
{/* Desktop CTAs */}
<div className="hidden lg:flex items-center gap-3 p-2">
<Link
href="/newsletter"
className="px-[1.5rem] py-[1rem] rounded-[0.5rem] border border-[#868686] text-[1.125rem] font-bold text-[#222221] hover:bg-[#222221] hover:text-white transition-colors"
className="px-6 py-4 rounded-lg border border-[#868686] text-[1.125rem] font-bold text-[#222221] hover:bg-[#222221] hover:text-white transition-colors"
>
Newsletter
</Link>
<Link
href="/challenge"
className="px-[1.5rem] py-[1rem] rounded-[0.5rem] bg-[#f6a701] text-[1.125rem] font-bold text-[#222221] hover:brightness-95 transition-all"
className="px-6 py-4 rounded-lg bg-[#f6a701] text-[1.125rem] font-bold text-[#222221] hover:brightness-95 transition-all"
>
7-Tage-Challenge
</Link>
</div>
{/* Mobile hamburger — animated to ✕ */}
<button
className="lg:hidden flex flex-col justify-center gap-[5px] p-2 -mr-2"
onClick={() => setMenuOpen((o) => !o)}
aria-label="Menü öffnen"
>
<span className={`block w-6 h-[2px] bg-[#222221] transition-all duration-300 origin-center ${menuOpen ? "rotate-45 translate-y-[7px]" : ""}`} />
<span className={`block w-6 h-[2px] bg-[#222221] transition-all duration-300 ${menuOpen ? "opacity-0" : ""}`} />
<span className={`block w-6 h-[2px] bg-[#222221] transition-all duration-300 origin-center ${menuOpen ? "-rotate-45 -translate-y-[7px]" : ""}`} />
</button>
</div>
{/* Mobile dropdown — max-h animation */}
<div
className={`lg:hidden overflow-hidden transition-all duration-300 ease-in-out ${
menuOpen ? "max-h-[32rem] pb-6" : "max-h-0"
}`}
>
<nav className="flex flex-col gap-1 px-4">
{navLinks.map((link) =>
link.href.startsWith("#") ? (
<a
key={link.href}
href={link.href}
onClick={(e) => handleAnchorClick(e, link.href)}
className="text-[1.125rem] font-semibold text-[#222221] hover:text-[#f6a701] transition-colors py-3 border-b border-[#e8e3db] last:border-0"
>
{link.label}
</a>
) : (
<Link
key={link.href}
href={link.href}
onClick={() => setMenuOpen(false)}
className="text-[1.125rem] font-semibold text-[#222221] hover:text-[#f6a701] transition-colors py-3 border-b border-[#e8e3db] last:border-0"
>
{link.label}
</Link>
)
)}
<div className="flex flex-col gap-3 pt-4">
<Link
href="/newsletter"
className="text-center px-6 py-3 rounded-lg border border-[#868686] text-[1rem] font-bold text-[#222221] hover:bg-[#222221] hover:text-white transition-colors"
>
Newsletter
</Link>
<Link
href="/challenge"
className="text-center px-6 py-3 rounded-lg bg-[#f6a701] text-[1rem] font-bold text-[#222221] hover:brightness-95 transition-all"
>
7-Tage-Challenge
</Link>
</div>
</nav>
</div>
</header>
);
+16 -31
View File
@@ -1,32 +1,22 @@
export function Newsletter() {
return (
<section className="py-16 w-full">
<section className="py-10 lg:py-16 w-full">
<div className="px-4 md:px-8 lg:px-[5rem] w-full">
{/* Outer section padding — same 80px horizontal as all other sections */}
<div className="px-[5rem] w-full">
{/* Card: stacked on mobile, side-by-side on lg+ */}
<div className="bg-[#f8f3ec] flex flex-col lg:flex-row gap-8 lg:gap-[3.5rem] items-start lg:items-center px-6 lg:px-8 py-8 lg:py-0 rounded-xl w-full">
{/* Rounded card: cream bg, 32px inner padding, 56px gap between copy and form */}
<div className="bg-[#f8f3ec] flex gap-[3.5rem] items-center px-8 rounded-xl w-full">
{/* Left: copy — fixed width 612px so form always gets the remaining flex-1 */}
<div className="flex gap-8 items-start py-4 shrink-0 w-[38.25rem]">
{/* Decorative envelope icon, tilted -4° as per design */}
<div className="flex items-center justify-center shrink-0 w-[4.23rem] h-[3.71rem]">
{/* Left: copy — full width mobile, fixed 612px desktop */}
<div className="flex gap-6 lg:gap-8 items-start w-full lg:w-[38.25rem] lg:shrink-0 lg:py-4">
<div className="flex items-center justify-center shrink-0 w-[3.5rem] h-[3.5rem] lg:w-[4.23rem] lg:h-[3.71rem]">
<div className="-rotate-4 -scale-y-100">
<img
alt=""
src="/newsletter-icon.svg"
className="w-16 h-[3.438rem] block"
/>
<img alt="" src="/newsletter-icon.svg" className="w-12 lg:w-16 h-auto block" />
</div>
</div>
{/* Heading + body */}
<div className="flex flex-col gap-4 flex-1 min-w-0 text-[#222221]">
<div className="flex flex-col gap-3 lg:gap-4 flex-1 min-w-0 text-[#222221]">
<p
className="font-semibold text-[1.75rem] leading-normal"
style={{ fontFamily: "var(--font-lora)" }}
className="font-semibold leading-normal"
style={{ fontFamily: "var(--font-lora)", fontSize: "clamp(1.25rem, 2.5vw, 1.75rem)" }}
>
Starte mit einer Woche voller Klarheit
</p>
@@ -37,16 +27,14 @@ export function Newsletter() {
</div>
</div>
{/* Right: form — takes remaining space, centered vertically */}
<div className="flex flex-1 items-center self-stretch min-w-0">
<div className="flex flex-1 flex-col gap-4 min-w-0">
{/* Input + submit button side by side */}
<div className="flex gap-4 items-stretch w-full">
{/* Right: form — full width on mobile */}
<div className="flex flex-1 items-center lg:self-stretch w-full min-w-0">
<div className="flex flex-1 flex-col gap-4 min-w-0 w-full">
<div className="flex flex-col sm:flex-row gap-3 items-stretch w-full">
<input
type="email"
placeholder="Deine E-Mail-Adresse"
className="flex-1 min-w-0 bg-white border border-[#d9d9d9] rounded-lg px-6 py-3 text-[1rem] text-[#868686] font-normal outline-none focus:border-[#f6a701] transition-colors"
className="flex-1 min-w-0 bg-white border border-[#d9d9d9] rounded-lg px-5 py-3 text-[1rem] text-[#868686] font-normal outline-none focus:border-[#f6a701] transition-colors"
/>
<button
type="submit"
@@ -55,12 +43,9 @@ export function Newsletter() {
Jetzt anmelden
</button>
</div>
{/* Privacy note */}
<p className="text-[0.75rem] text-[#222221] font-normal leading-normal">
Ich achte auf deine Daten. Kein Spam, jederzeit abbestellbar.
</p>
</div>
</div>
+16 -27
View File
@@ -3,21 +3,18 @@ import Link from "next/link";
const tools = [
{
icon: { src: "/icon-rocket.svg", w: "3.375rem", h: "4.122rem", transform: "-scale-y-100" },
pr: "3.375rem",
title: "Mini-Challenge",
description: "In 7 Tagen zu mehr Klarheit. Kleine Gewohnheiten, die Großes bewirken.",
cta: { label: "Starten", href: "/challenge" },
},
{
icon: { src: "/icon-todo.svg", w: "3rem", h: "3.879rem", transform: "-scale-y-100" },
pr: "2rem",
title: "ToDo-Karten",
description: "Das Werkzeug für Fokus im Alltag. bringe Struktur in deine Aufgaben und gewinne Zeit zurück.",
description: "Das Werkzeug für Fokus im Alltag. Bringe Struktur in deine Aufgaben und gewinne Zeit zurück.",
cta: { label: "Entdecken", href: "/werkzeuge" },
},
{
icon: { src: "/icon-newsletter.svg", w: "3rem", h: "2.579rem", transform: "-rotate-4 -scale-y-100" },
pr: "2rem",
title: "Impulse & Tipps",
description: "Wöchentliche Impulse mit konkreten Ideen und erprobten Tipps für weniger Reibung und mehr Leichtigkeit.",
cta: { label: "Anmelden", href: "/newsletter" },
@@ -26,64 +23,56 @@ const tools = [
export function Tools() {
return (
<div id="werkzeuge" className="flex flex-col gap-[3rem] items-start pb-[4rem] pt-[2rem] w-full bg-[#f5f0e8]">
<div id="werkzeuge" className="flex flex-col gap-8 lg:gap-[3rem] items-start pb-10 lg:pb-[4rem] pt-8 lg:pt-[2rem] w-full bg-[#f5f0e8]">
{/* Section header */}
<div className="flex flex-col gap-[0.5rem] items-start px-[5rem] w-full whitespace-nowrap overflow-clip">
<div className="flex flex-col gap-2 items-start px-4 md:px-8 lg:px-[5rem] w-full">
<p className="font-bold text-[#f6a701] text-[1.25rem]">
Meine Werkzeuge
</p>
<p
className="font-semibold text-[#222221] text-[1.75rem]"
style={{ fontFamily: "var(--font-lora)" }}
className="font-semibold text-[#222221]"
style={{ fontFamily: "var(--font-lora)", fontSize: "clamp(1.375rem, 2.5vw, 1.75rem)" }}
>
Werkzeuge für einen leichteren Alltag.
</p>
</div>
{/* Tools grid */}
<div className="flex gap-[2.5rem] h-[12.5rem] items-center overflow-clip px-[5rem] w-full">
{/* Tools grid: 1-col mobile → 2-col md → 3-col lg */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 lg:gap-[2.5rem] px-4 md:px-8 lg:px-[5rem] w-full">
{tools.map((tool) => (
<div
key={tool.title}
className="flex flex-[1_0_0] gap-[2rem] h-full items-start min-w-px overflow-clip relative"
style={{ paddingRight: tool.pr }}
>
<div key={tool.title} className="flex gap-6 items-start">
{/* Icon */}
<div className="flex items-center justify-center shrink-0">
<div className={tool.icon.transform}>
<div className="relative" style={{ width: tool.icon.w, height: tool.icon.h }}>
<img
alt=""
src={tool.icon.src}
className="absolute inset-0 w-full h-full"
/>
<img alt="" src={tool.icon.src} className="absolute inset-0 w-full h-full" />
</div>
</div>
</div>
{/* Card content */}
<div
className="flex flex-[1_0_0] flex-col h-full items-start justify-between min-w-px overflow-clip p-[0.5rem] text-[#222221] [word-break:break-word]"
>
<div className="flex flex-col gap-[1rem] items-start w-full">
<div className="flex flex-col gap-4 items-start min-w-0 text-[#222221] [word-break:break-word]">
<div className="flex flex-col gap-3 w-full">
<p
className="font-semibold leading-normal text-[1.75rem] w-full"
className="font-semibold leading-normal text-[1.5rem] lg:text-[1.75rem] w-full"
style={{ fontFamily: "var(--font-lora)" }}
>
{tool.title}
</p>
<p className="font-normal leading-[1.5rem] text-[1rem] w-full">
<p className="font-normal leading-6 text-[1rem] w-full">
{tool.description}
</p>
</div>
<Link
href={tool.cta.href}
className="font-bold leading-normal text-[1rem] whitespace-nowrap hover:text-[#f6a701] transition-colors"
className="font-bold text-[1rem] whitespace-nowrap hover:text-[#f6a701] transition-colors"
>
{tool.cta.label}
</Link>
</div>
</div>
))}
</div>
+26 -1
View File
@@ -13,7 +13,32 @@
}
html {
scroll-padding-top: 6.25rem; /* navbar height */
scroll-padding-top: 5rem; /* mobile navbar height */
}
@media (min-width: 1024px) {
html {
scroll-padding-top: 6.25rem; /* desktop navbar height */
}
}
/* Hero image: gradient mask only on desktop where image is right-column */
.hero-mask {
-webkit-mask-image: none;
mask-image: none;
}
@media (min-width: 1024px) {
.hero-mask {
-webkit-mask-image:
linear-gradient(to right, transparent 0%, black 14%),
linear-gradient(to bottom, transparent 0%, black 10%);
-webkit-mask-composite: destination-in;
mask-image:
linear-gradient(to right, transparent 0%, black 14%),
linear-gradient(to bottom, transparent 0%, black 10%);
mask-composite: intersect;
}
}
body {