feat(ui): Startseite mutiger gestaltet
- Hero: deutlich groessere Headline, langsam atmendes Bild, Wabenraster, Honigtropfen als Scroll-Hinweis, Hauptaktion in Honig - "Sechs Schritte" als Weg: eine Honiglinie fuellt sich beim Scrollen und laesst die Waben der Schritte nacheinander aufleuchten (waagerecht ab lg, senkrecht auf dem Handy; reduzierte Bewegung: sofort gefuellt) - Philosophie mit Waben statt Nummern, Verantwortung als geteiltes Layout mit mitlaufender Ueberschrift - Bilder mit versetztem Honigrahmen, Wabenraster auf dunklen Flaechen, grosse Anfuehrungszeichen bei den Kundenstimmen - Knopf-Varianten "inverted"/"accent" fuer dunkle Flaechen ersetzen !-Overrides, die den Fuell-Effekt ausgehebelt haetten - Fix: Ueberschrift der Kundenstimmen war Waldgruen auf Waldgruen Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
3cb639c154
commit
3de17ca070
9 files changed
+298
-103
No files matched your search
@@ -1,4 +1,6 @@
|
||||
import { Container, SectionHeading, LinkButton } from "@/components/ui";
|
||||
import { Container, SectionHeading, LinkButton, FramedMedia } from "@/components/ui";
|
||||
import { ProcessPath } from "@/components/process-path";
|
||||
import { HoneycombPattern, HexMark } from "@/components/honeycomb";
|
||||
import { ScrollReveal } from "@/components/scroll-reveal";
|
||||
import { ContentImage } from "@/components/content-image";
|
||||
import { StarRating } from "@/components/star-rating";
|
||||
@@ -23,21 +25,7 @@ export async function ProcessTimeline() {
|
||||
className="mx-auto"
|
||||
/>
|
||||
</ScrollReveal>
|
||||
<div className="mt-16 grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-8">
|
||||
{steps.map((step, i) => (
|
||||
<ScrollReveal key={step.number} delay={i * 0.06}>
|
||||
<div>
|
||||
<span className="text-honey-dark text-sm tracking-wide-caps">
|
||||
{step.number}
|
||||
</span>
|
||||
<h3 className="mt-2 text-lg text-forest">{step.title}</h3>
|
||||
<p className="mt-2 text-xs text-ink/70 leading-relaxed">
|
||||
{step.text}
|
||||
</p>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
))}
|
||||
</div>
|
||||
<ProcessPath steps={steps} />
|
||||
</Container>
|
||||
</section>
|
||||
);
|
||||
@@ -56,7 +44,7 @@ export async function RegionalSection() {
|
||||
);
|
||||
return (
|
||||
<section className="py-24">
|
||||
<Container className="grid md:grid-cols-2 gap-12 items-center">
|
||||
<Container className="grid md:grid-cols-2 gap-16 lg:gap-24 items-center">
|
||||
<ScrollReveal className="order-2 md:order-1">
|
||||
<SectionHeading
|
||||
eyebrow={t.home.regionalSection.eyebrow}
|
||||
@@ -74,14 +62,16 @@ export async function RegionalSection() {
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
<ScrollReveal className="order-1 md:order-2" delay={0.1}>
|
||||
<ContentImage
|
||||
src={content["home.regionalSection.image"] || null}
|
||||
alt=""
|
||||
tone="forest"
|
||||
className="aspect-[4/5] w-full"
|
||||
label={t.home.regionalSection.eyebrow}
|
||||
sizes="(min-width: 768px) 50vw, 100vw"
|
||||
/>
|
||||
<FramedMedia side="left">
|
||||
<ContentImage
|
||||
src={content["home.regionalSection.image"] || null}
|
||||
alt=""
|
||||
tone="forest"
|
||||
className="aspect-[4/5] w-full"
|
||||
label={t.home.regionalSection.eyebrow}
|
||||
sizes="(min-width: 768px) 50vw, 100vw"
|
||||
/>
|
||||
</FramedMedia>
|
||||
</ScrollReveal>
|
||||
</Container>
|
||||
</section>
|
||||
@@ -94,26 +84,30 @@ export async function Sustainability() {
|
||||
const content = await getContentValues(["home.sustainability.items"], locale);
|
||||
const items = parseListTitled(content["home.sustainability.items"]);
|
||||
return (
|
||||
<section className="py-24 bg-cream/60">
|
||||
<Container>
|
||||
<ScrollReveal>
|
||||
<SectionHeading
|
||||
eyebrow={t.home.sustainability.eyebrow}
|
||||
title={t.home.sustainability.title}
|
||||
align="center"
|
||||
className="mx-auto"
|
||||
/>
|
||||
<section className="py-28 bg-cream/60">
|
||||
{/* Geteilt statt Viererreihe: die Ueberschrift laeuft mit, die Punkte
|
||||
werden als ruhige Liste gelesen. */}
|
||||
<Container className="grid gap-12 lg:grid-cols-12 lg:gap-16">
|
||||
<ScrollReveal className="lg:col-span-5">
|
||||
<div className="lg:sticky lg:top-32">
|
||||
<SectionHeading eyebrow={t.home.sustainability.eyebrow} title={t.home.sustainability.title} />
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
<div className="mt-14 grid sm:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
<ul className="divide-y divide-ink/10 border-y border-ink/10 lg:col-span-7">
|
||||
{items.map((item, i) => (
|
||||
<ScrollReveal key={item.title} delay={i * 0.08}>
|
||||
<h3 className="text-lg text-forest">{item.title}</h3>
|
||||
<p className="mt-2 text-sm text-ink/65 leading-relaxed">
|
||||
{item.text}
|
||||
</p>
|
||||
</ScrollReveal>
|
||||
<li key={item.title}>
|
||||
<ScrollReveal delay={i * 0.08}>
|
||||
<div className="group grid grid-cols-[auto_1fr] gap-x-5 py-7">
|
||||
<HexMark className="mt-2 h-3 w-3 text-honey transition-transform duration-500 ease-[var(--ease-arrive)] group-hover:rotate-90" />
|
||||
<div>
|
||||
<h3 className="text-2xl text-forest">{item.title}</h3>
|
||||
<p className="mt-2 max-w-[55ch] text-ink/70 leading-relaxed">{item.text}</p>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</li>
|
||||
))}
|
||||
</div>
|
||||
</ul>
|
||||
</Container>
|
||||
</section>
|
||||
);
|
||||
@@ -128,16 +122,18 @@ export async function BusinessTeaser() {
|
||||
);
|
||||
return (
|
||||
<section className="py-24">
|
||||
<Container className="grid md:grid-cols-2 gap-12 items-center">
|
||||
<Container className="grid md:grid-cols-2 gap-16 lg:gap-24 items-center">
|
||||
<ScrollReveal>
|
||||
<ContentImage
|
||||
src={content["home.businessTeaser.image"] || null}
|
||||
alt=""
|
||||
tone="honey"
|
||||
className="aspect-[4/5] w-full"
|
||||
label={t.home.businessTeaser.eyebrow}
|
||||
sizes="(min-width: 768px) 50vw, 100vw"
|
||||
/>
|
||||
<FramedMedia>
|
||||
<ContentImage
|
||||
src={content["home.businessTeaser.image"] || null}
|
||||
alt=""
|
||||
tone="honey"
|
||||
className="aspect-[4/5] w-full"
|
||||
label={t.home.businessTeaser.eyebrow}
|
||||
sizes="(min-width: 768px) 50vw, 100vw"
|
||||
/>
|
||||
</FramedMedia>
|
||||
</ScrollReveal>
|
||||
<ScrollReveal delay={0.1}>
|
||||
<SectionHeading
|
||||
@@ -173,8 +169,9 @@ export async function Reviews() {
|
||||
: t.home.reviews.testimonials.map((r) => ({ ...r, rating: 5, authorUrl: null }));
|
||||
|
||||
return (
|
||||
<section className="py-24 bg-forest text-cream">
|
||||
<Container>
|
||||
<section className="relative overflow-hidden py-28 bg-forest text-cream">
|
||||
<HoneycombPattern className="text-honey-light/[0.07]" size={30} />
|
||||
<Container className="relative">
|
||||
<ScrollReveal>
|
||||
<SectionHeading
|
||||
eyebrow={t.home.reviews.eyebrow}
|
||||
@@ -192,10 +189,13 @@ export async function Reviews() {
|
||||
<div className="mt-14 grid md:grid-cols-3 gap-10">
|
||||
{items.slice(0, 6).map((review, i) => (
|
||||
<ScrollReveal key={`${review.author}-${i}`} delay={i * 0.08}>
|
||||
<span aria-hidden="true" className="block font-serif text-7xl leading-[0.6] text-honey-light/70">
|
||||
„
|
||||
</span>
|
||||
<StarRating value={review.rating} />
|
||||
<span className="sr-only">{t.home.reviews.starsOutOf5(review.rating)}</span>
|
||||
<p className="mt-4 text-cream/85 leading-relaxed italic">
|
||||
„{review.quote}“
|
||||
<p className="mt-4 font-serif text-xl text-cream/90 leading-relaxed italic">
|
||||
{review.quote}
|
||||
</p>
|
||||
{/* Zuordnung zur Quelle: die Nutzungsbedingungen der Places API
|
||||
verlangen, dass eine angezeigte Rezension zu Google
|
||||
|
||||
Reference in new issue
Block a user