import type { Metadata } from "next";
import Image from "next/image";
import { useTranslations } from "next-intl";
import { getTranslations, setRequestLocale } from "next-intl/server";
import { Link } from "@/i18n/navigation";
import { ScrollDownCue } from "@/components/ScrollDownCue";
import { ScrollReveal } from "@/components/ScrollReveal";
import { JsonLd } from "@/components/JsonLd";
import { connectDB } from "@/lib/db";
import { PortfolioItem } from "@/models/PortfolioItem";
import { Testimonial } from "@/models/Testimonial";
import { getSettings } from "@/lib/settings";
import { buildPageMetadata, getSiteUrl } from "@/lib/seo";
import { getReviewAverage } from "@/lib/reviewAverage";
import { type TestimonialItem } from "@/components/ReviewsWidget";

export const dynamic = "force-dynamic";

export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }): Promise<Metadata> {
  const { locale } = await params;
  const th = await getTranslations({ locale, namespace: "home" });
  const settings = await getSettings();
  const seo = settings.seoSettings;
  const description = (locale === "en" ? seo?.defaultMetaDescriptionEn || seo?.defaultMetaDescription : seo?.defaultMetaDescription) || th("heroText");
  return buildPageMetadata({
    locale,
    path: "",
    title: th("metaTitle"),
    description,
  });
}

export default async function HomePage({
  params,
}: {
  params: Promise<{ locale: string }>;
}) {
  const { locale } = await params;
  setRequestLocale(locale);

  await connectDB();
  const [featuredDocs, testimonialDocs, settings, reviewAverage] = await Promise.all([
    PortfolioItem.find({ featured: true, visible: true, publishedAt: { $not: { $gt: new Date() } } })
      .sort({ sortOrder: 1 })
      .limit(4)
      .lean(),
    Testimonial.find({ visible: true }).sort({ sortOrder: 1 }).lean(),
    getSettings(),
    getReviewAverage(),
  ]);
  const featuredImages = featuredDocs.map((d) => ({
    src: d.coverImage || d.images[0],
    alt: (locale === "en" && d.titleEn) || d.title,
    label: d.category,
  }));
  const testimonials = testimonialDocs.map((d) => ({
    authorName: d.authorName,
    realName: d.realName,
    quote: (locale === "en" && d.quoteEn) || d.quote,
    context: (locale === "en" && d.contextEn) || d.context,
    imagePath: d.imagePath,
    source: d.source,
    rating: d.rating,
  }));

  const inv = settings.invoiceSettings;
  const seo = settings.seoSettings;
  const siteUrl = getSiteUrl();
  const sameAs = Object.values(settings.socialLinks || {}).filter((v) => v && v.startsWith("http"));

  return (
    <main>
      <JsonLd
        data={{
          "@context": "https://schema.org",
          "@type": "LocalBusiness",
          name: inv?.businessName || "Rakku Photography",
          image: `${siteUrl}${seo?.ogImage || "/img/hero.jpg"}`,
          url: siteUrl,
          ...(seo?.businessPhone ? { telephone: seo.businessPhone } : {}),
          ...(seo?.priceRange ? { priceRange: seo.priceRange } : {}),
          ...(seo?.openingHours ? { openingHours: seo.openingHours } : {}),
          ...(reviewAverage
            ? {
                aggregateRating: {
                  "@type": "AggregateRating",
                  ratingValue: reviewAverage.average,
                  reviewCount: reviewAverage.count,
                },
              }
            : {}),
          ...(inv?.street
            ? {
                address: {
                  "@type": "PostalAddress",
                  streetAddress: inv.street,
                  postalCode: inv.postCode,
                  addressLocality: inv.city,
                  addressCountry: inv.countryCode || "DE",
                },
              }
            : {}),
          // Feste Koordinaten statt Geocoding zur Laufzeit — die Geschäftsadresse
          // ändert sich praktisch nie, ein externer API-Aufruf bei jedem
          // Seitenaufruf wäre unnötig. Bei Adressänderung hier mit aktualisieren
          // (z. B. via nominatim.openstreetmap.org neu ermitteln).
          ...(inv?.city === "Bielefeld"
            ? { geo: { "@type": "GeoCoordinates", latitude: 52.0168528, longitude: 8.569387 } }
            : {}),
          areaServed: [
            { "@type": "City", name: "Bielefeld" },
            { "@type": "AdministrativeArea", name: "Ostwestfalen-Lippe" },
          ],
          ...(sameAs.length > 0 ? { sameAs } : {}),
        }}
      />
      <Hero />
      <FeaturedWork images={featuredImages} />
      <About />
      <TestimonialBigQuote items={testimonials} />
      <ClosingCta />
    </main>
  );
}

// "Main"-Hero (entschieden 03.09.2026, Runde 2): zweispaltiges Raster statt
// vollflächigem Hintergrundfoto — Text links, ein leicht gedrehtes, gerahmtes
// Foto rechts mit einem versetzten Orts-/Genre-Schild. War beim ersten
// echten Umbau (Round 135) fälschlich als "bleibt unverändert" behandelt
// worden (mit dem schon vorher live vorhandenen Vollbild-Hero verwechselt) —
// hier korrigiert, siehe Merkblatt.
function Hero() {
  const t = useTranslations("home");

  return (
    // Nur noch LINKS Rand (pr-0) statt beidseitig — im Mockup läuft das
    // Foto bis zum echten Seitenrand durch und wird dort vom
    // `overflow-hidden` der Section angeschnitten (der leicht gedrehte
    // Rahmen ragt durch die Rotation minimal über die Spalte hinaus und
    // wird dadurch sauber gekappt statt komplett sichtbar zu bleiben) —
    // das war der "halb eingeschnittene Effekt", den der Nutzer meinte
    // (08.09.2026), keine bloße Abstandsfrage.
    // Feste Stufen statt stufenloser vw-Skalierung (Standard-Regel ab
    // 08.09.2026, siehe [[project_rakku_v2_redesign]]): vw-basierte
    // clamp()-Werte reagieren auf JEDE Fensterbreite, auch beim
    // Rauszoomen oder bei "krummen" logischen Auflösungen (z. B. einem
    // 14"-MacBook, dessen CSS-Pixel-Breite von einem externen Full-HD-
    // Monitor abweicht) — dadurch wirkt die Seite nie ganz stabil. Feste
    // Werte an den üblichen Breakpoints (sm/lg/xl) sehen an jeder
    // KONKRETEN Bildschirmgröße exakt gleich aus, ohne dazwischen zu
    // "schwimmen".
    <section className="relative min-h-screen flex items-center overflow-hidden pl-6 sm:pl-10 lg:pl-16 xl:pl-24 pt-[140px] pb-16 bg-[var(--rk-bg)]">
      {/* Hero-Hintergrund (Till, 09.09.2026, Variante "B"): der leere schwarze
          Raum links wirkte zu langweilig. Drei zurückhaltende Ebenen —
          gerichtetes Kupfer-Studiolicht von oben rechts, eine weiche
          Eck-Vignette für Tiefe und eine übergroße "RAKKU"-Geist-Wortmarke
          (nur Outline) hinter dem Text. Alles rein dekorativ, pointer-events
          aus, aria-hidden. */}
      {/* Gerichteter Kupfer-Schein von oben rechts (Studiolicht-Anmutung) —
          kräftiger und höher/rechter als der frühere zentrale Glow. */}
      <div className="absolute inset-0 pointer-events-none [background:radial-gradient(ellipse_50%_78%_at_82%_22%,rgba(201,138,75,0.34),transparent_62%)]" />
      {/* Diagonales Streiflicht + weiche Eck-Vignette. */}
      <div
        className="absolute inset-0 pointer-events-none"
        style={{
          background:
            "linear-gradient(118deg, transparent 44%, rgba(201,138,75,0.10) 62%, transparent 80%), radial-gradient(ellipse at 55% 46%, transparent 52%, rgba(0,0,0,0.5) 100%)",
        }}
      />
      {/* Geist-Wortmarke: übergroß, nur als Outline, nach RECHTS versetzt und
          durch die Überschrift laufend (Till 09.09.2026: "doppelt so groß ...
          etwas nach rechts ... auch unter die Überschrift gehen", "überall
          geil"). Vertikal über den flex-Container mittig zur Section (= zur
          H1-Zeile), horizontal per padding-left nach rechts geschoben.
          Größe + pl je Breakpoint fest gestaffelt, so austariert dass der
          rechte Wortrand IMMER vor dem festen Foto (420/520/620px) endet und
          nie am Viewport abgeschnitten wird — geprüft 1024–2560. Die zwei
          obersten Stufen (>=1800 / >=2200) per <style>, da Tailwinds
          arbitrary min-[...]-Varianten hier nicht zuverlässig griffen. */}
      <div
        aria-hidden="true"
        className="pointer-events-none absolute inset-0 hidden select-none overflow-hidden lg:flex lg:items-center"
      >
        <span
          className="rk-wordmark hero-ghost -translate-y-[12%] whitespace-nowrap leading-none lg:pl-12 lg:text-[9rem] xl:pl-[4.5rem] xl:text-[11rem] 2xl:pl-20 2xl:text-[10.5rem]"
          style={{ color: "transparent", WebkitTextStroke: "1.5px rgba(245,245,244,0.06)" }}
        >
          RAKKU
        </span>
      </div>
      <style>{`
        @media (min-width: 1800px) { .hero-ghost { font-size: 13rem; padding-left: 7rem; } }
        @media (min-width: 2200px) { .hero-ghost { font-size: 18rem; padding-left: 14rem; } }
      `}</style>

      {/* Die Eckklammern kommen jetzt aus SiteHeader (site-weit, fix am
          Viewport, kennt den Banner-Versatz) statt hier einzeln zu leben —
          siehe SiteHeader.tsx. */}

      {/* Foto-Spalte in festen Stufen statt vw-Skalierung (siehe Kommentar
          oben an der Section) — 420/520/620px an lg/xl/2xl, angelehnt an
          die zuletzt bestätigten ~37vw-Werte bei 1024/1280/1536px, aber
          jetzt als stabile Breakpoint-Werte statt kontinuierlicher
          Funktion. Wächst ab 2xl (1536px) nicht mehr weiter. */}
      <div className="relative w-full grid gap-6 sm:gap-8 lg:gap-10 xl:gap-14 lg:grid-cols-[1fr_420px] xl:grid-cols-[1fr_520px] 2xl:grid-cols-[1fr_620px] items-center">
        {/* lg:pl-10: nochmal etwas mehr Einrückung als der erste Versuch
            (pl-4), auf erneuten Wunsch des Nutzers (08.09.2026). */}
        <div className="text-center lg:text-left lg:pl-10">
          <p className="text-xs uppercase tracking-[0.35em] text-[var(--rk-ink-muted)]">{t("subheading")}</p>
          <h1 className="rk-wordmark mt-[22px] text-4xl sm:text-5xl lg:text-6xl xl:text-7xl leading-[1.03]">
            Rakku <span className="text-[var(--rk-accent)]">Photography</span>
          </h1>
          {/* Zurück auf die feste .rk-accent-rule-Breite (2.5rem) — der
              Versuch, die Breite an den "R"-Glyphen zu binden, wirkte in
              der Praxis zu lang; auf Wunsch des Nutzers (08.09.2026)
              einfach wieder der ursprüngliche Zustand. */}
          <div className="rk-accent-rule mx-auto lg:mx-0" />
          <p className="mt-[30px] text-[15px] leading-relaxed text-[var(--rk-ink-muted)] max-w-2xl mx-auto lg:mx-0">
            {t("heroText")}
          </p>
          <div className="mt-10 flex flex-wrap items-center justify-center lg:justify-start gap-4">
            <Link
              href="/portfolio"
              className="inline-block border border-white/30 px-8 py-3 text-xs uppercase tracking-[0.25em] text-[var(--rk-ink)] hover:border-white hover:bg-white/5 transition-colors"
            >
              {t("portfolioButton")}
            </Link>
            <Link
              href="/account/new-order"
              className="inline-block border border-white/30 bg-white/10 px-8 py-3 text-xs uppercase tracking-[0.25em] text-[var(--rk-ink)] hover:border-white hover:bg-white/15 transition-colors"
            >
              {t("bookButton")}
            </Link>
          </div>
        </div>

        {/* translate-x schiebt den gedrehten Rahmen noch etwas über den
            rechten Rand hinaus, damit die untere rechte Spitze wirklich am
            Rand verschwindet statt kurz davor sichtbar zu bleiben (Wunsch
            des Nutzers, 08.09.2026) — reine Fein-Justage on top of dem
            randständigen Grid von eben. */}
        <div className="relative mx-auto lg:mx-0 lg:ml-auto lg:translate-x-6 w-full lg:max-w-[420px] xl:max-w-[520px] 2xl:max-w-[620px]">
          {/* rotate-[2.4deg] jetzt auch auf dem Glow (fehlte vorher) — der
              Glow ist ein eigenes, nicht gedrehtes Rechteck hinter dem
              gedrehten Fotorahmen; im Spalt, den die Drehung an den Ecken
              freilegt, schimmerte seine eigene rechteckige Kante als
              harte Grau-Stufe durch (vom Nutzer gemeldeter "Bug" oberhalb
              des Fotos, unabhängig vom section-weiten Glow, den ich davor
              fälschlich ganz entfernt hatte). Mit derselben Drehung liegt
              der Glow jetzt geometrisch exakt hinter dem Rahmen. */}
          {/* blur-[4px] -> blur-3xl: bei nur 4px blieb die rechteckige
              Kante des Glow-Divs trotz des zur Mitte hin transparenten
              Verlaufs schwach sichtbar — wirkte wie eine "unsichtbare Box"
              hinter dem Foto (vom Nutzer gemeldet, 08.09.2026). Mit
              deutlich mehr Weichzeichnung löst sich die Kante komplett
              auf, es bleibt nur noch reines Umgebungslicht übrig. */}
          <div className="absolute -inset-8 blur-3xl rotate-[2.4deg] pointer-events-none [background:radial-gradient(ellipse_70%_70%_at_50%_40%,rgba(201,138,75,0.5),transparent_72%)]" />
          <div className="rk-grain relative aspect-[4/5] overflow-hidden rotate-[2.4deg] shadow-[0_50px_100px_-30px_rgba(0,0,0,0.7)]">
            <Image
              src="/img/hero.jpg"
              alt=""
              fill
              priority
              sizes="(min-width: 1536px) 620px, (min-width: 1280px) 520px, (min-width: 1024px) 420px, 60vw"
              className="object-cover object-[50%_18%]"
            />
            <div className="absolute inset-0 [background:linear-gradient(180deg,transparent_55%,rgba(16,16,18,0.75))]" />
          </div>
          <div className="absolute z-[2] left-[-1.5rem] bottom-10 -rotate-[2.4deg] bg-[var(--rk-bg)] border border-[var(--rk-line)] px-[22px] py-[14px] text-[11px] uppercase tracking-[0.14em] text-[var(--rk-ink-muted)] shadow-[0_20px_40px_rgba(0,0,0,0.5)]">
            {t("heroTagLocation")}
            <b className="block mt-1 text-[13px] tracking-[0.06em] normal-case text-[var(--rk-ink)]">{t("heroTagGenre")}</b>
          </div>
        </div>
      </div>

      <ScrollDownCue targetId="featured" label={t("scrollCue")} />
    </section>
  );
}

// Fixes 4-Kachel-Raster (entschieden 03.09.2026) statt des responsiven
// 2/3-Spalten-Rasters von vorher — echte Fotos zuerst (mit ihrer echten
// Kategorie als Label), erst wenn weniger als 4 Beiträge als "Featured"
// markiert sind, wird mit hero.jpg aufgefüllt (genau wie im bestätigten
// Mockup, das aus demselben Grund hero.jpg als vierte Kachel wiederverwendet
// hat — nie mit einem frei erfundenen Foto).
function FeaturedWork({ images: dbImages }: { images: { src: string; alt: string; label?: string }[] }) {
  const t = useTranslations("home");

  const fallbackPool = [
    { src: "/img/hero.jpg", alt: t("featuredFallbackAlt"), label: "Cosplay" },
    { src: "/img/featured-1.jpg", alt: t("featured1Alt"), label: "Cosplay" },
    { src: "/img/featured-2.jpg", alt: t("featured2Alt"), label: "Convention" },
    { src: "/img/featured-3.jpg", alt: t("featured3Alt"), label: "Portrait" },
  ].filter((f) => !dbImages.some((d) => d.src === f.src));

  const images = [...dbImages];
  while (images.length < 4 && fallbackPool.length > 0) {
    images.push(fallbackPool.shift()!);
  }

  return (
    // Einheitlicher vertikaler Abstand (py-40 = 160px) für alle
    // Flach-Hintergrund-Sektionen der Startseite (Featured/About/
    // Testimonial), auf Wunsch des Nutzers (08.09.2026: "alle Segmente
    // sollen den selben Abstand haben") — nur der Hero ist bewusst die
    // Ausnahme (eigene min-h-screen-Logik). Vorher hatte jede Sektion
    // ihren eigenen, unterschiedlichen py-Wert (120/140px hier, 190px bei
    // About, 130/170px beim Testimonial).
    <section id="featured" className="rk-shell py-[160px]">
      <ScrollReveal className="text-center">
        <p className="text-xs uppercase tracking-[0.35em] text-[var(--rk-ink-muted)]">
          {t("featuredEyebrow")}
        </p>
        <h2 className="rk-wordmark mt-4 text-xl sm:text-3xl">{t("featuredTitle")}</h2>
        <div className="rk-accent-rule rk-accent-rule--center" />
      </ScrollReveal>

      {/* max-w von 1040px auf 1600px angehoben (Wunsch des Nutzers,
          08.09.2026: "das ganze Segment kann größer werden wie im
          Mockup") — 1040px war 1:1 aus dem 1200px-Mockup übernommen und
          wirkte auf einem echten großen Monitor arg klein im Verhältnis
          zum Rest der (inzwischen mitskalierenden) Seite. 1600px matcht
          den site-eigenen --breakpoint-3xl-Wert, bleibt also innerhalb
          der schon etablierten "großer Monitor"-Konvention. */}
      <div className="mt-14 max-w-[1600px] mx-auto grid grid-cols-2 sm:grid-cols-4 gap-[10px]">
        {images.map((img, i) => (
          <ScrollReveal key={img.src} delayMs={i * 120}>
            <div className="relative aspect-[3/4] overflow-hidden group">
              <Image
                src={img.src}
                alt={img.alt}
                fill
                sizes="(min-width: 640px) 25vw, 50vw"
                className="object-cover transition-transform duration-700 ease-out group-hover:scale-105"
              />
              <div className="absolute inset-0 ring-1 ring-inset ring-white/10" />
              {img.label && (
                <span className="absolute left-[10px] bottom-[10px] bg-[rgba(16,16,18,0.65)] px-[9px] py-1 text-[9.5px] uppercase tracking-[0.1em] text-[var(--rk-ink)]">
                  {img.label}
                </span>
              )}
            </div>
          </ScrollReveal>
        ))}
      </div>
    </section>
  );
}

// "Vereinte Karte" (entschieden 03.09.2026, Runde 3+4): Foto, Kurzbio und
// Vision-Zitat in EINER Karte statt in getrennten Bild-/Text-Spalten. Der
// diagonale Einschnitt (clip-path) markiert bewusst genau EINE strukturelle
// Zäsur auf der ganzen Seite — direkt hinter der Portfolio-Vorschau, siehe
// Merkblatt "ein bewusster struktureller Bruch pro Seite, nicht keiner,
// nicht mehrere".
function About() {
  const t = useTranslations("home");

  return (
    <section
      id="about"
      // Feste Stufen statt vw-Skalierung (Standard-Regel ab 08.09.2026,
      // siehe Hero oben) — ein fixer 3rem-Anstieg würde auf breiten
      // Monitoren fast unsichtbar flach wirken, deshalb an lg/xl/2xl
      // schrittweise steiler statt kontinuierlich mit vw.
      className="relative -mt-16 py-[160px] px-6 [clip-path:polygon(0_3rem,100%_0,100%_100%,0_100%)] lg:[clip-path:polygon(0_4rem,100%_0,100%_100%,0_100%)] xl:[clip-path:polygon(0_5rem,100%_0,100%_100%,0_100%)] 2xl:[clip-path:polygon(0_6rem,100%_0,100%_100%,0_100%)] bg-[var(--rk-bg)] flex justify-center"
    >
      {/* max-w-[600px] statt max-w-lg (512px) — im Mockup ist die Karte
          560px breit, bei 512px brach "Fotograf aus Bielefeld" auf zwei
          Zeilen um (Fund vom Nutzer, 08.09.2026). */}
      <ScrollReveal className="w-full max-w-[600px] bg-[var(--rk-surface)] border border-[var(--rk-line)] px-8 py-12 sm:px-12 text-center shadow-[0_40px_80px_-20px_rgba(0,0,0,0.5)]">
        <div className="relative w-24 h-24 mx-auto mb-5 rounded-full overflow-hidden border border-[var(--rk-line)]">
          <Image src="/img/rakku-portrait.jpg" alt={t("aboutPortraitAlt")} fill sizes="6rem" className="object-cover" />
        </div>
        <p className="text-xs uppercase tracking-[0.35em] text-[var(--rk-ink-muted)]">{t("aboutTitle")}</p>
        <h2 className="rk-wordmark mt-2 text-xl sm:text-2xl">{t("aboutSubtitle")}</h2>
        <p className="mt-[18px] text-sm leading-relaxed text-[var(--rk-ink-muted)]">{t("aboutTeaser")}</p>
        <div className="rk-accent-rule rk-accent-rule--center" />
        <blockquote className="mt-[18px] text-[15px] italic leading-relaxed text-[var(--rk-ink)]">
          „{t("visionQuote")}“
        </blockquote>
        <Link
          href="/ueber-mich"
          className="mt-6 inline-block text-xs uppercase tracking-[0.18em] border-b border-white/30 hover:border-white pb-1 transition-colors"
        >
          {t("aboutMoreLink")}
        </Link>
      </ScrollReveal>
    </section>
  );
}

// "Großes Hintergrund-Zitat" (entschieden 03.09.2026, Runde 3): ein
// riesiges, kaum sichtbares Anführungszeichen-Glyph hinter EINER
// hervorgehobenen Kundenstimme statt eines Fließbands aus vielen Zitaten
// (das Fließband bleibt als QuickReviewsMarquee für die Sterne-Bewertungen
// erhalten, siehe oben auf der Seite). Zeigt die am besten bewertete
// Stimme; bei Gleichstand die zuerst sortierte (sortOrder).
function TestimonialBigQuote({ items }: { items: TestimonialItem[] }) {
  const t = useTranslations("home");
  const featured = [...items].sort((a, b) => b.rating - a.rating)[0];
  if (!featured) return null;

  return (
    <section className="rk-grain relative overflow-hidden text-center px-6 py-[160px] [background:linear-gradient(180deg,var(--rk-bg)_0%,var(--rk-surface)_220px)]">
      {/* Der eigentliche Denkfehler die ganze Zeit: ich habe die CSS-Box
          (top/height) behandelt, als wäre sie identisch mit dem sichtbaren
          Zeichen — ist sie nicht. Per Pixel-Scan des echten Renderings
          nachgemessen: bei top-[194px]/204px Boxhöhe erschien die
          tatsächlich sichtbare Tinte des „-Zeichens erst bei ~72% der Box
          (relativ zur Section: 342-390px), weil das Zeichen tief in seiner
          eigenen Schriftbox hängt (typisch für ein tiefstehendes
          Anführungszeichen). Deshalb sah es trotz "richtiger" Box-Position
          unten beim Zitat statt oben bei der Überschrift aus (vom Nutzer
          gemeldet, 08.09.2026). Fix: Box um genau den gemessenen Versatz
          (117px) nach oben verschoben, damit die SICHTBARE Tinte (nicht
          die Box) auf der Überschrift (231-266px) landet. */}
      <p
        aria-hidden="true"
        // Opacity per Inline-Style statt Tailwind-Klasse — .rk-wordmark
        // überschreibt sonst die Farbe (siehe SiteHeader.tsx-Kommentar zur
        // selben Kaskaden-Falle bei den Ecklammern).
        // 0.045 (die Mockup-CSS-Quelle) las sich auf dem echten Bildschirm
        // als praktisch unsichtbar ("ganz verschwunden", vom Nutzer
        // gemeldet, 08.09.2026) — im JPEG-Referenzbild wirkt derselbe Wert
        // durch Kompressionsartefakte etwas kräftiger, als er auf einem
        // echten Display tatsächlich rendert. Auf 0.09 angehoben, damit es
        // zuverlässig als Wasserzeichen wahrnehmbar ist.
        style={{ color: "rgba(245, 245, 244, 0.09)" }}
        className="rk-wordmark absolute left-[calc(50%+29px)] top-[45px] -translate-x-1/2 text-[204px] leading-none select-none"
      >
        „
      </p>
      {/* mt-16 entfernt — das addierte sich zusätzlich zum section-eigenen
          py-[160px] und machte den Abstand nach oben (264px) fast doppelt
          so groß wie nach unten (128px), gemessen per getBoundingClientRect
          (Fund vom Nutzer, 08.09.2026). Featured/About haben dieses
          zusätzliche mt- gar nicht erst, nur Testimonial hatte es. */}
      <ScrollReveal className="relative max-w-xl mx-auto">
        <p className="text-xs uppercase tracking-[0.35em] text-[var(--rk-ink-muted)]">{t("testimonialsEyebrow")}</p>
        <h2 className="rk-wordmark mt-4 text-xl sm:text-3xl">{t("testimonialsTitle")}</h2>
        <div className="mt-9">
          {featured.rating > 0 && (
            <p className="text-[15px] tracking-[3px] text-[var(--rk-accent)]">
              {"★".repeat(Math.round(featured.rating))}
              <span className="text-[var(--rk-ink-muted)]">{"★".repeat(5 - Math.round(featured.rating))}</span>
            </p>
          )}
          <blockquote className="mt-5 text-xl sm:text-2xl italic leading-snug">{featured.quote}</blockquote>
          <p className="mt-6 text-xs uppercase tracking-[0.14em] text-[var(--rk-ink-muted)]">
            <b className="text-[var(--rk-ink)] not-italic font-normal">
              {featured.realName ? `${featured.realName} „${featured.authorName}“` : featured.authorName}
            </b>
            {featured.context ? ` · ${featured.context}` : ""}
          </p>
        </div>
      </ScrollReveal>
    </section>
  );
}

// "Vollflächiges Bild" (entschieden 03.09.2026, Runde 6) — schließt die
// Startseite ab, dieselbe Rolle wie ein Call-to-Action-Banner am Ende einer
// Landingpage. Bewusst das allerletzte Element vor dem Footer.
function ClosingCta() {
  const t = useTranslations("home");

  return (
    // py-[160px] ergänzt (vorher gar kein eigenes Padding, nur
    // min-h-[480px] + zentriert) — auf Wunsch des Nutzers (08.09.2026)
    // denselben Abstands-Rhythmus wie Featured/About/Testimonial tragen,
    // min-h bleibt als Untergrenze für sehr kurzen Text erhalten.
    <section className="relative min-h-[480px] py-[160px] flex items-center justify-center text-center overflow-hidden px-6">
      <Image src="/img/hero.jpg" alt="" fill sizes="100vw" className="object-cover" />
      {/* rk-grain jetzt auf dem Scrim statt auf der Section (Begründung
          siehe Commit) — WICHTIG: .rk-grain setzt selbst `position:
          relative`, das schlug in der Kaskade die Tailwind-Klasse
          "absolute" (dieselbe Falle wie schon bei den Ecklammern/dem
          Header-Korn), wodurch der Scrim komplett aus seiner
          Überlagerungs-Position rutschte und einen NEUEN, noch
          auffälligeren Farbsprung erzeugte (81 statt 23 direkt unter der
          Grenze — sofort per Pixel-Sample aufgefallen, bevor es live
          ging). position:absolute deshalb per Inline-Style erzwungen. */}
      <div
        style={{ position: "absolute" }}
        className="rk-grain inset-0 [background:linear-gradient(180deg,var(--rk-surface),rgba(16,16,18,0.55)_140px,rgba(16,16,18,0.85))]"
      />
      <div className="relative z-[1]">
        <p className="text-xs uppercase tracking-[0.35em] text-[var(--rk-ink-muted)]">{t("closingCtaEyebrow")}</p>
        <h2 className="rk-wordmark mt-3.5 text-2xl sm:text-4xl">{t("closingCtaTitle")}</h2>
        <p className="mt-[18px] max-w-md mx-auto text-sm leading-relaxed text-[var(--rk-ink-muted)]">
          {t("closingCtaText")}
        </p>
        <Link
          href="/account/new-order"
          className="mt-[34px] inline-block border border-[var(--rk-accent)] bg-[var(--rk-accent)] px-8 py-3 text-xs uppercase tracking-[0.25em] font-semibold text-[var(--rk-bg)] hover:opacity-90 transition-opacity"
        >
          {t("bookButton")}
        </Link>
      </div>
    </section>
  );
}

