feat(ui): Startseite mit eigenstaendigen Abschnitten statt Schablonen-Zickzack
- Aktuelle Ernte: bei ein, zwei Produkten steht die Ueberschrift als eigene Spalte daneben, statt ueber einem halb leeren Dreierraster. - Herkunft: Foto randlos ueber die halbe Seitenbreite, Text daneben, ohne Rahmen. - Philosophie: typografische Reihe mit Trennlinien und grossen Serif-Titeln statt vier Icon-Karten. - Region: breites Bild, der Text liegt als Tafel ueberlappend darueber. - Geschaeftskunden: kompakte Tafel mit randlosem Bild statt eines dritten grossen Bild/Text-Wechsels. Inhalte, Texte und Content-Schluessel bleiben unveraendert. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
1fa8ca246a
commit
7e467a9ddf
2 files changed
+72
-68
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import { Container, SectionHeading, LinkButton, FramedMedia } from "@/components/ui";
|
||||
import { Container, SectionHeading, LinkButton } from "@/components/ui";
|
||||
import { HoneycombPattern, HexMark } from "@/components/honeycomb";
|
||||
import { ScrollReveal } from "@/components/scroll-reveal";
|
||||
import { ContentImage } from "@/components/content-image";
|
||||
@@ -17,16 +17,25 @@ export async function CurrentHarvest({
|
||||
reviewSummaries?: Map<string, { average: number | null; count: number }>;
|
||||
}) {
|
||||
const t = getDictionary(await getLocale());
|
||||
// Ausserhalb der Erntezeit sind es oft nur ein, zwei Glaeser. Dann steht die
|
||||
// Ueberschrift als eigene Spalte daneben, statt ueber einem halb leeren
|
||||
// Dreierraster.
|
||||
const isFew = products.length <= 2;
|
||||
return (
|
||||
<section className="py-24">
|
||||
<Container>
|
||||
<ScrollReveal>
|
||||
<SectionHeading
|
||||
title={t.home.currentHarvest.title}
|
||||
subtitle={t.home.currentHarvest.subtitle}
|
||||
/>
|
||||
<Container className={isFew ? "grid gap-12 lg:grid-cols-12 lg:gap-16" : ""}>
|
||||
<ScrollReveal className={isFew ? "lg:col-span-4" : ""}>
|
||||
<div className={isFew ? "lg:sticky lg:top-32" : ""}>
|
||||
<SectionHeading title={t.home.currentHarvest.title} subtitle={t.home.currentHarvest.subtitle} />
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
<div className="mt-14 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-14">
|
||||
<div
|
||||
className={
|
||||
isFew
|
||||
? "grid grid-cols-1 gap-x-8 gap-y-14 sm:grid-cols-2 lg:col-span-8"
|
||||
: "mt-14 grid grid-cols-1 gap-x-8 gap-y-14 sm:grid-cols-2 lg:grid-cols-3"
|
||||
}
|
||||
>
|
||||
{products.map((product, index) => (
|
||||
<ProductCard
|
||||
key={product.id}
|
||||
@@ -55,24 +64,23 @@ export async function OriginStory() {
|
||||
);
|
||||
const facts = parseListSimple(content["home.originStory.facts"]);
|
||||
return (
|
||||
<section className="py-28 bg-cream/60">
|
||||
<Container className="grid md:grid-cols-2 gap-16 lg:gap-24 items-center">
|
||||
<ScrollReveal>
|
||||
<FramedMedia>
|
||||
// Randlos geteilt: das Foto fuellt die linke Haelfte bis an den
|
||||
// Fensterrand, der Text steht daneben — kein Rahmen, keine Karte.
|
||||
<section className="grid bg-cream/60 md:grid-cols-2">
|
||||
<ScrollReveal className="h-full">
|
||||
<ContentImage
|
||||
src={content["home.originStory.image"] || null}
|
||||
alt=""
|
||||
tone="forest"
|
||||
className="aspect-[4/5] w-full"
|
||||
rounded={false}
|
||||
className="h-full min-h-[24rem] w-full md:min-h-[40rem]"
|
||||
label={t.home.originStory.eyebrow}
|
||||
sizes="(min-width: 768px) 50vw, 100vw"
|
||||
/>
|
||||
</FramedMedia>
|
||||
</ScrollReveal>
|
||||
<ScrollReveal delay={0.1}>
|
||||
<SectionHeading
|
||||
title={t.home.originStory.title}
|
||||
/>
|
||||
<div className="flex items-center px-6 py-20 sm:px-10 lg:px-20 xl:px-28">
|
||||
<ScrollReveal delay={0.1} className="max-w-xl">
|
||||
<SectionHeading title={t.home.originStory.title} />
|
||||
<p className="mt-6 text-ink/75 leading-relaxed">{content["home.originStory.paragraph1"]}</p>
|
||||
<p className="mt-4 text-ink/75 leading-relaxed">{content["home.originStory.paragraph2"]}</p>
|
||||
<ul className="mt-8 grid gap-2.5 text-sm text-ink/75 sm:grid-cols-2">
|
||||
@@ -83,11 +91,11 @@ export async function OriginStory() {
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<LinkButton href="/herkunft" variant="secondary" className="mt-8">
|
||||
<LinkButton href="/herkunft" variant="secondary" className="mt-10">
|
||||
{t.home.originStory.cta}
|
||||
</LinkButton>
|
||||
</ScrollReveal>
|
||||
</Container>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -98,26 +106,22 @@ export async function Philosophy() {
|
||||
const content = await getContentValues(["home.philosophy.items"], locale);
|
||||
const items = parseListTitled(content["home.philosophy.items"]);
|
||||
return (
|
||||
<section className="py-24">
|
||||
<section className="py-24 md:py-28">
|
||||
<Container>
|
||||
<ScrollReveal>
|
||||
<SectionHeading
|
||||
title={t.home.philosophy.title}
|
||||
align="center"
|
||||
className="mx-auto"
|
||||
/>
|
||||
<SectionHeading title={t.home.philosophy.title} />
|
||||
</ScrollReveal>
|
||||
<div className="mt-16 grid sm:grid-cols-2 lg:grid-cols-4 gap-x-8 gap-y-14">
|
||||
{/* Typografische Reihe statt Icon-Karten: vier Grundsaetze, getrennt
|
||||
durch Linien, die Titel tragen das Gewicht. */}
|
||||
<div className="mt-14 grid border-t border-ink/15 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{items.map((item, i) => (
|
||||
<ScrollReveal key={item.title} delay={i * 0.08}>
|
||||
<div className={`border-t border-ink/15 pt-6 ${i % 2 === 1 ? "lg:mt-10" : ""}`}>
|
||||
{/* Wabe statt "01"-Nummer: die vier Punkte sind gleichrangig, keine Reihenfolge. */}
|
||||
<HexMark filled={i % 2 === 0} className="h-5 w-5 text-honey" />
|
||||
<h3 className="mt-4 text-2xl text-forest">{item.title}</h3>
|
||||
<p className="mt-3 text-sm text-ink/70 leading-relaxed">
|
||||
{item.text}
|
||||
</p>
|
||||
</div>
|
||||
<ScrollReveal
|
||||
key={item.title}
|
||||
delay={i * 0.06}
|
||||
className="border-b border-ink/15 py-8 sm:pr-8 lg:border-b-0 lg:border-l lg:px-8 lg:first:border-l-0 lg:first:pl-0"
|
||||
>
|
||||
<h3 className="font-serif text-3xl leading-tight text-forest text-balance">{item.title}</h3>
|
||||
<p className="mt-3 max-w-[34ch] text-sm leading-relaxed text-ink/70">{item.text}</p>
|
||||
</ScrollReveal>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Container, SectionHeading, LinkButton, FramedMedia } from "@/components/ui";
|
||||
import { Container, SectionHeading, LinkButton } from "@/components/ui";
|
||||
import { ProcessPath } from "@/components/process-path";
|
||||
import { HoneycombPattern, HexMark } from "@/components/honeycomb";
|
||||
import { ScrollReveal } from "@/components/scroll-reveal";
|
||||
@@ -43,11 +43,24 @@ export async function RegionalSection() {
|
||||
);
|
||||
return (
|
||||
<section className="py-24">
|
||||
<Container className="grid md:grid-cols-2 gap-16 lg:gap-24 items-center">
|
||||
<ScrollReveal className="order-2 md:order-1">
|
||||
<SectionHeading
|
||||
title={t.home.regionalSection.title}
|
||||
<Container>
|
||||
{/* Breites Bild, der Text legt sich als Tafel darueber — Tiefe statt
|
||||
eines weiteren Bild-neben-Text-Wechsels. */}
|
||||
<ScrollReveal>
|
||||
<ContentImage
|
||||
src={content["home.regionalSection.image"] || null}
|
||||
alt=""
|
||||
tone="forest"
|
||||
className="aspect-[4/3] w-full sm:aspect-[16/9]"
|
||||
label={t.home.regionalSection.eyebrow}
|
||||
sizes="(min-width: 1280px) 1200px, 100vw"
|
||||
/>
|
||||
</ScrollReveal>
|
||||
<ScrollReveal
|
||||
delay={0.1}
|
||||
className="relative mx-4 -mt-16 max-w-2xl bg-background p-8 shadow-[0_24px_50px_-34px_rgba(36,53,43,0.45)] sm:mx-10 sm:p-10 lg:-mt-40 lg:ml-16 lg:p-12"
|
||||
>
|
||||
<SectionHeading title={t.home.regionalSection.title} />
|
||||
<p className="mt-6 text-ink/75 leading-relaxed">{content["home.regionalSection.paragraph1"]}</p>
|
||||
<p className="mt-4 text-ink/75 leading-relaxed">{content["home.regionalSection.paragraph2"]}</p>
|
||||
<div className="mt-8 flex flex-wrap gap-4">
|
||||
@@ -59,18 +72,6 @@ export async function RegionalSection() {
|
||||
</LinkButton>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
<ScrollReveal className="order-1 md:order-2" delay={0.1}>
|
||||
<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>
|
||||
);
|
||||
@@ -120,27 +121,26 @@ export async function BusinessTeaser() {
|
||||
);
|
||||
return (
|
||||
<section className="py-24">
|
||||
<Container className="grid md:grid-cols-2 gap-16 lg:gap-24 items-center">
|
||||
<ScrollReveal>
|
||||
<FramedMedia>
|
||||
<Container>
|
||||
{/* Kompakte Tafel statt eines dritten grossen Bild/Text-Blocks: ein
|
||||
Angebot fuer eine kleinere Zielgruppe, entsprechend zurueckhaltend. */}
|
||||
<ScrollReveal className="grid overflow-hidden border border-ink/10 bg-background md:grid-cols-5">
|
||||
<div className="flex flex-col justify-center p-8 sm:p-12 md:col-span-3 lg:p-16">
|
||||
<SectionHeading title={t.home.businessTeaser.title} />
|
||||
<p className="mt-6 max-w-[55ch] text-ink/75 leading-relaxed">{content["home.businessTeaser.paragraph"]}</p>
|
||||
<LinkButton href="/unternehmen" className="mt-8 self-start">
|
||||
{t.home.businessTeaser.cta}
|
||||
</LinkButton>
|
||||
</div>
|
||||
<ContentImage
|
||||
src={content["home.businessTeaser.image"] || null}
|
||||
alt=""
|
||||
tone="honey"
|
||||
className="aspect-[4/5] w-full"
|
||||
rounded={false}
|
||||
className="aspect-[4/3] w-full md:col-span-2 md:aspect-auto md:h-full md:min-h-[22rem]"
|
||||
label={t.home.businessTeaser.eyebrow}
|
||||
sizes="(min-width: 768px) 50vw, 100vw"
|
||||
sizes="(min-width: 768px) 40vw, 100vw"
|
||||
/>
|
||||
</FramedMedia>
|
||||
</ScrollReveal>
|
||||
<ScrollReveal delay={0.1}>
|
||||
<SectionHeading
|
||||
title={t.home.businessTeaser.title}
|
||||
/>
|
||||
<p className="mt-6 text-ink/75 leading-relaxed">{content["home.businessTeaser.paragraph"]}</p>
|
||||
<LinkButton href="/unternehmen" className="mt-8">
|
||||
{t.home.businessTeaser.cta}
|
||||
</LinkButton>
|
||||
</ScrollReveal>
|
||||
</Container>
|
||||
</section>
|
||||
|
||||
Reference in new issue
Block a user