---
import "../styles/global.css";
import "../lib/iconify-offline";
import Header from "../components/Header.svelte";
import HeaderOverlay from "../components/HeaderOverlay.svelte";
import Footer from "../components/Footer.svelte";
import TopBanner from "../components/TopBanner.svelte";
import Breadcrumbs from "../lib/ui/Breadcrumbs.svelte";
import {
  getNavigationByKey,
  NavigationKeys,
  getPages,
  getPosts,
  getFooterBySlug,
  getFullwidthBannerBySlug,
  getPageConfigBySlug,
} from "../lib/cms";
import type { NavLinkEntry, FullwidthBannerEntry } from "../lib/cms";
import { resolveImageUrls, ensureTransformedImage } from "../lib/rusty-image";
import {
  DEFAULT_SOCIAL_IMAGE_URL,
  ROW_RESOLVE,
  SITE_NAME,
  SOCIAL_IMAGE_TRANSFORM,
} from "../lib/constants";
import TranslationProvider from "../components/TranslationProvider.svelte";
import { t, T } from "../lib/translations";
import { getCmsFromCache } from "../lib/cms-cache-state";
import type { TranslationKey } from "../lib/translations";
import { marked } from "marked";

marked.setOptions({ gfm: true });

/** Aufgelöster Banner (Objekt mit image[]) oder Slug (string). */
type TopBannerInput = FullwidthBannerEntry | string | null | undefined;

function isResolvedBanner(v: TopBannerInput): v is FullwidthBannerEntry {
  return typeof v === "object" && v !== null && "name" in v;
}

interface Props {
  title?: string;
  description?: string;
  /** Headline der aktuellen Page (wird im TopBanner angezeigt, falls gepflegt). */
  headline?: string;
  /** Subheadline der aktuellen Page (Markdown). */
  subheadline?: string;
  /** Fullwidth-Banner: aufgelöst (Objekt mit image[]) bei _resolve, sonst Slug. Nur wenn gesetzt → TopBanner anzeigen. */
  topFullwidthBanner?: TopBannerInput;
  /** true = Layout zeigt TopBanner (Titel dort). false = kein TopBanner, Seite zeigt Titel im Content. */
  showBannerInLayout?: boolean;
  /** Optional: absoluter oder relativer URL für og:image / twitter:image (z. B. Post-Bild). */
  image?: string | null;
  /** Optional: Breadcrumb-Items. Letzter Eintrag ohne href = aktuelle Seite. translationKey überschreibt label (übersetzt). */
  breadcrumbItems?: { href?: string; label?: string; translationKey?: TranslationKey }[];
}

const {
  title = "RustyAstro",
  description,
  headline,
  subheadline,
  topFullwidthBanner,
  showBannerInLayout = false,
  image: imageProp = null,
  breadcrumbItems = undefined,
} = Astro.props;

// Übersetzungen aus Middleware (Astro.locals.translations) – für TranslationProvider und Breadcrumbs
const translations: Record<string, string> = Astro.locals.translations ?? {};
/** JSON für script type="application/json": </ escapen, damit das Tag nicht geschlossen wird. */
function safeJsonScriptContent(obj: Record<string, string>): string {
  return JSON.stringify(obj).replace(/<\//g, "\\u003c/");
}
const resolvedBreadcrumbItems =
  breadcrumbItems?.map((item) => ({
    href: item.href,
    label:
      item.translationKey != null
        ? t(translations, item.translationKey)
        : (item.label ?? ""),
  })) ?? [];

// Header: Navigation (flache Links + navgroup-Untermenüs, vgl. angelverein-vachdorf.de Layout.astro)
type HeaderNavChild = { href: string; label: string };
type HeaderNavItem =
  | HeaderNavChild
  | { label: string; href?: string; children: HeaderNavChild[] };
let headerNavItems: HeaderNavItem[] = [];
/** Führenden Slash ignorieren (CMS liefert z. B. "slug": "/about"). */
function normalizeSlug(s: string | undefined): string {
  return (s ?? "").replace(/^\//, "").trim();
}
function getSlugFromEntry(entry: NavLinkEntry): string {
  if (typeof entry === "string") return entry;
  const e = entry as { _slug?: string; slug?: string };
  return e.slug ?? e._slug ?? "";
}
function normalizeNavHref(url: string): string {
  return url.startsWith("/") || url.startsWith("http")
    ? url
    : `/${url.replace(/^\//, "")}`;
}
/** CMS-Kanon-Slug ohne führenden Slash (z. B. bi/vachdorf) → URL-Pfad. */
function pageSlugToPath(canonicalSlug: string): string {
  const s = (canonicalSlug ?? "").trim();
  if (!s || s === "home") return "/";
  return (
    "/" +
    s.split("/")
      .filter(Boolean)
      .map((seg) => encodeURIComponent(seg))
      .join("/")
  );
}
function resolveNavEntryToChild(
  entry: NavLinkEntry,
  slugToLabel: Map<string, string>,
  slugToPageHref: Map<string, string>,
  slugToPostHref: Map<string, string>,
): HeaderNavChild | null {
  const asObj =
    typeof entry === "object" && entry !== null
      ? (entry as { url?: string; linkName?: string; name?: string })
      : null;
  if (asObj?.url && String(asObj.url).trim() !== "") {
    const href = normalizeNavHref(String(asObj.url).trim());
    const label = asObj.linkName ?? asObj.name ?? asObj.url ?? "";
    return { href, label };
  }
  const raw = getSlugFromEntry(entry);
  const slug = normalizeSlug(raw) || "home";
  const label = slugToLabel.get(slug) ?? slug;
  const postHref = slugToPostHref.get(slug);
  const pageSlug = slugToPageHref.get(slug) ?? slug;
  const hrefSlug = normalizeSlug(pageSlug) || "home";
  const href =
    postHref ??
    (hrefSlug === "home" ? "/" : pageSlugToPath(hrefSlug));
  return { href, label };
}
try {
  const nav = await getNavigationByKey(NavigationKeys.header, {
    locale: "de",
    resolve: "links",
  });
  const rawLinks = nav?.links ?? [];
  const [pages, posts] = await Promise.all([getPages(), getPosts()]);
  const slugToLabel = new Map<string, string>();
  /** Für Pages: Nav-Key (_slug oder slug) → kanonischer Slug für URL (ohne führenden Slash). */
  const slugToPageHref = new Map<string, string>();
  for (const p of pages) {
    const label = p.linkName ?? p.name ?? p.headline ?? p.slug ?? p._slug ?? "";
    const canonicalSlug = normalizeSlug(p.slug ?? p._slug) || "home";
    const keySlug = normalizeSlug(p.slug);
    const keyUnderscore = normalizeSlug(p._slug);
    if (keySlug) {
      slugToLabel.set(keySlug, label);
      slugToPageHref.set(keySlug, canonicalSlug);
    }
    if (keyUnderscore && keyUnderscore !== keySlug) {
      slugToLabel.set(keyUnderscore, label);
      slugToPageHref.set(keyUnderscore, canonicalSlug);
    }
  }
  /** Für Posts: Nav-Key → kanonische URL /post/{slug} (slug = URL). */
  const slugToPostHref = new Map<string, string>();
  for (const p of posts) {
    const label = p.linkName ?? p.headline ?? p.slug ?? p._slug ?? "";
    const urlSlug = normalizeSlug(p.slug ?? p._slug);
    const canonical = urlSlug ? `/post/${encodeURIComponent(urlSlug)}` : "";
    const keySlug = normalizeSlug(p.slug);
    const keyUnderscore = normalizeSlug(p._slug);
    if (keySlug) {
      slugToLabel.set(keySlug, label);
      slugToPostHref.set(keySlug, canonical);
    }
    if (keyUnderscore && keyUnderscore !== keySlug) {
      slugToLabel.set(keyUnderscore, label);
      slugToPostHref.set(keyUnderscore, canonical);
    }
  }
  for (const entry of rawLinks) {
    const asRecord =
      typeof entry === "object" && entry !== null
        ? (entry as Record<string, unknown>)
        : null;
    const rawLinksInner = asRecord?.links;
    const isNavGroup =
      asRecord &&
      typeof asRecord.label === "string" &&
      Array.isArray(rawLinksInner) &&
      rawLinksInner.length > 0 &&
      typeof rawLinksInner[0] === "object" &&
      rawLinksInner[0] !== null;

    if (isNavGroup) {
      const children: HeaderNavChild[] = [];
      for (const sub of rawLinksInner as unknown[]) {
        const child = resolveNavEntryToChild(
          sub as NavLinkEntry,
          slugToLabel,
          slugToPageHref,
          slugToPostHref,
        );
        if (child) children.push(child);
      }
      if (children.length === 0) continue;
      const urlRaw = asRecord.url;
      const parentHref =
        typeof urlRaw === "string" && urlRaw.trim() !== ""
          ? normalizeNavHref(urlRaw.trim())
          : undefined;
      headerNavItems.push({
        label: asRecord.label as string,
        ...(parentHref ? { href: parentHref } : {}),
        children,
      });
      continue;
    }

    const flat = resolveNavEntryToChild(
      entry,
      slugToLabel,
      slugToPageHref,
      slugToPostHref,
    );
    if (flat) headerNavItems.push(flat);
  }
} catch {
  // CMS nicht erreichbar
}

// Social-Media-Links aus navigation-social-media (icon = iconify string)
interface SocialLink {
  href: string;
  icon: string;
  label?: string;
}
let socialLinks: SocialLink[] = [];
try {
  const socialNav = await getNavigationByKey(NavigationKeys.socialMedia, {
    locale: "de",
    resolve: "all",
  });
  const rawSocialLinks = socialNav?.links ?? [];
  for (const entry of rawSocialLinks) {
    const asObj =
      typeof entry === "object" && entry !== null
        ? (entry as {
            url?: string;
            icon?: string;
            linkName?: string;
            name?: string;
          })
        : null;
    if (!asObj?.url) continue;
    const href =
      asObj.url.startsWith("/") || asObj.url.startsWith("http")
        ? asObj.url
        : `/${asObj.url.replace(/^\//, "")}`;
    const icon = asObj.icon ?? "mdi:link";
    const label = asObj.linkName ?? asObj.name ?? "";
    socialLinks.push({ href, icon, label });
  }
} catch {
  /* Social-Links optional */
}

// Footer laden (mit Row-Resolve)
let footerData: Awaited<ReturnType<typeof getFooterBySlug>> = null;
try {
  footerData = await getFooterBySlug("footer-main", {
    locale: "de",
    resolve: ROW_RESOLVE,
  });
} catch {
  // CMS nicht erreichbar
}

// Logo und SEO-Templates aus page_config (wie windwiderstand).
let logoUrl: string | null = null;
/** Bei SVG: serverseitig geladener Markup für Inline-Render (currentColor statt img-Tag). */
let logoSvgHtml: string | null = null;
let pageConfig: Awaited<ReturnType<typeof getPageConfigBySlug>> | null = null;
try {
  // Zuerst page-config-default (häufiger Slug), dann default – vermeidet doppelten 404
  pageConfig =
    (await getPageConfigBySlug("page-config-default", {
      locale: "de",
      resolve: "logo",
    })) ??
    (await getPageConfigBySlug("default", { locale: "de", resolve: "logo" }));
  const rawLogo = pageConfig?.logo;
  /** Logo-URL: String (z. B. `/api/assets/…`) oder aufgelöstes img-Objekt. */
  const logoFileUrl =
    typeof rawLogo === "string" && rawLogo.trim()
      ? rawLogo.trim().startsWith("//")
        ? `https:${rawLogo.trim()}`
        : rawLogo.trim()
      : ((
          rawLogo as
            | { src?: string; _slug?: string; file?: { url?: string } }
            | undefined
        )?.src ??
        (rawLogo as { _slug?: string; file?: { url?: string } } | undefined)
          ?._slug ??
        (rawLogo as { file?: { url?: string } } | undefined)?.file?.url);
  if (logoFileUrl) {
    const u =
      typeof logoFileUrl === "string" && logoFileUrl.startsWith("//")
        ? `https:${logoFileUrl}`
        : logoFileUrl;
    const isSvg = u.split("?")[0].toLowerCase().endsWith(".svg");
    if (isSvg) {
      // SVGs können nicht transformiert werden — direkt als URL nutzen
      logoUrl = u.startsWith("/") ? `${import.meta.env.PUBLIC_CMS_URL}${u}` : u;
      try {
        const res = await fetch(logoUrl);
        if (res.ok) {
          const text = (await res.text()).trim();
          if (text.includes("<svg")) logoSvgHtml = text;
        }
      } catch {
        /* z. B. Build ohne erreichbares CMS → Fallback img mit logoUrl */
      }
    } else {
      logoUrl = await ensureTransformedImage(u, {
        height: 56,
        fit: "contain",
        format: "webp",
      });
    }
  }
} catch {
  /* Logo optional */
}

// SEO Title/Description: Page/Post-Wert + page_config-Template ($1 = Platzhalter, wie windwiderstand)
let seoTitle = title ?? "RustyAstro";
let seoDescription = description ?? "";
if (pageConfig?.seoTitle)
  seoTitle = pageConfig.seoTitle.replace(/\$1/g, seoTitle);
if (pageConfig?.seoDescription)
  seoDescription = pageConfig.seoDescription.replace(/\$1/g, seoDescription);

// SEO: canonical und Social-Image (nach logoUrl)
// Lokale Entwicklung: echte Origin (localhost:4321); sonst PUBLIC_SITE_URL / site aus Config
const siteFromEnv = (import.meta.env.SITE || "").replace(/\/$/, "");
const isLocalhost =
  Astro.url.origin.startsWith("http://localhost") ||
  Astro.url.origin.startsWith("http://127.0.0.1");
const baseUrl = isLocalhost
  ? Astro.url.origin
  : siteFromEnv || Astro.url.origin;
const pathname = Astro.url.pathname || "/";
const canonical = `${baseUrl}${pathname}`;

// Social-Image immer über RustyImage (externe URLs transformieren; lokale Pfade unverändert nutzen).
// Fallback: Wenn kein Bild/Logo und Transform fehlschlägt → DEFAULT_SOCIAL_IMAGE_URL (absolut), damit WhatsApp/og immer ein Vorschaubild hat.
const socialImageSource = imageProp ?? logoUrl ?? null;
const needsTransform =
  !socialImageSource ||
  socialImageSource.startsWith("http://") ||
  socialImageSource.startsWith("https://");
const urlToTransform = socialImageSource ?? DEFAULT_SOCIAL_IMAGE_URL;
let socialImageResolved: string | null = null;
if (needsTransform) {
  try {
    const transformed = await ensureTransformedImage(
      urlToTransform,
      SOCIAL_IMAGE_TRANSFORM,
    );
    socialImageResolved = transformed.startsWith("/")
      ? `${baseUrl}${transformed}`
      : transformed;
  } catch {
    socialImageResolved = null;
  }
} else {
  // Bereits lokaler Pfad (z. B. von Post), nur baseUrl davor
  socialImageResolved = `${baseUrl}${urlToTransform.startsWith("/") ? "" : "/"}${urlToTransform}`;
}
const socialImage =
  socialImageResolved ??
  (urlToTransform.startsWith("http") ? urlToTransform : "");
const siteName =
  (import.meta.env.PUBLIC_SITE_NAME as string | undefined) || SITE_NAME;

// Top-Banner nur laden, wenn die Seite einen Banner anzeigen soll (showBannerInLayout + topFullwidthBanner)
let topBanner: FullwidthBannerEntry | null = null;
let topBannerResolvedImages: string[] = [];
if (
  showBannerInLayout &&
  topFullwidthBanner != null &&
  (typeof topFullwidthBanner === "string" ? topFullwidthBanner !== "" : true)
) {
  try {
    if (isResolvedBanner(topFullwidthBanner)) {
      topBanner = topFullwidthBanner;
      const bannerImages = Array.isArray(topBanner.image)
        ? topBanner.image
        : topBanner.image != null
          ? [topBanner.image]
          : [];
      if (bannerImages.length > 0) {
        topBannerResolvedImages = await resolveImageUrls(bannerImages, {
          width: 2000,
          height: 750,
          fit: "cover",
          format: "webp",
        });
      }
    } else if (
      typeof topFullwidthBanner === "string" &&
      topFullwidthBanner !== ""
    ) {
      topBanner = await getFullwidthBannerBySlug(topFullwidthBanner, {
        locale: "de",
      });
      const bannerImages = Array.isArray(topBanner?.image)
        ? topBanner.image
        : topBanner?.image != null
          ? [topBanner.image]
          : [];
      if (bannerImages.length > 0) {
        topBannerResolvedImages = await resolveImageUrls(bannerImages, {
          width: 2000,
          height: 750,
          fit: "cover",
          format: "webp",
        });
      }
    }
  } catch {
    // CMS nicht erreichbar oder kein Banner
  }
}

// Titelblock (Headline/Subheadline als Markdown), wenn kein Banner angezeigt wird
const showTitleInContent =
  !showBannerInLayout &&
  ((headline != null && headline !== "") ||
    (subheadline != null && subheadline !== ""));
const titleHeadlineHtml =
  showTitleInContent && headline?.trim()
    ? (marked.parseInline(headline) as string)
    : "";
const titleSubheadlineHtml =
  showTitleInContent && subheadline?.trim()
    ? (marked.parseInline(subheadline) as string)
    : "";
const cmsFromCache = getCmsFromCache();
---

<!doctype html>
<html lang="de">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <meta name="theme-color" content="#ffffff" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <link rel="alternate" type="application/rss+xml" title="Beiträge" href="/posts/rss.xml" />
    <link rel="icon" href="/favicons/favicon.ico" sizes="any" />
    <link
      rel="icon"
      type="image/png"
      sizes="16x16"
      href="/favicons/favicon-16x16.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="32x32"
      href="/favicons/favicon-32x32.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="96x96"
      href="/favicons/favicon-96x96.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="192x192"
      href="/favicons/android-icon-192x192.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="57x57"
      href="/favicons/apple-icon-57x57.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="60x60"
      href="/favicons/apple-icon-60x60.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="72x72"
      href="/favicons/apple-icon-72x72.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="76x76"
      href="/favicons/apple-icon-76x76.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="114x114"
      href="/favicons/apple-icon-114x114.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="120x120"
      href="/favicons/apple-icon-120x120.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="144x144"
      href="/favicons/apple-icon-144x144.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="152x152"
      href="/favicons/apple-icon-152x152.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="180x180"
      href="/favicons/apple-icon-180x180.png"
    />
    <link rel="manifest" href="/favicons/manifest.json" />
    <meta name="msapplication-TileColor" content="#ffffff" />
    <meta
      name="msapplication-TileImage"
      content="/favicons/ms-icon-144x144.png"
    />
    <meta
      name="msapplication-config"
      content="/favicons/browserconfig.xml"
    />
    <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#2d7a45" />
    <meta name="generator" content={Astro.generator} />
    <title>{seoTitle}</title>
    {seoDescription && <meta name="description" content={seoDescription} />}
    <link rel="canonical" href={canonical} />
    <link rel="sitemap" href="/sitemap-index.xml" />
    <!-- Open Graph -->
    <meta property="og:type" content="website" />
    <meta property="og:url" content={canonical} />
    <meta property="og:title" content={seoTitle} />
    {
      seoDescription && (
        <meta property="og:description" content={seoDescription} />
      )
    }
    {socialImage && <meta property="og:image" content={socialImage} />}
    {
      socialImage && (
        <>
          <meta
            property="og:image:width"
            content={String(SOCIAL_IMAGE_TRANSFORM.width)}
          />
          <meta
            property="og:image:height"
            content={String(SOCIAL_IMAGE_TRANSFORM.height)}
          />
        </>
      )
    }
    <meta property="og:locale" content="de_DE" />
    <meta property="og:site_name" content={siteName} />
    <!-- Twitter -->
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:url" content={canonical} />
    <meta name="twitter:title" content={seoTitle} />
    {
      seoDescription && (
        <meta name="twitter:description" content={seoDescription} />
      )
    }
    {socialImage && <meta name="twitter:image" content={socialImage} />}
    <!-- JSON-LD WebSite -->
    <script type="application/ld+json" set:html={JSON.stringify({
      "@context": "https://schema.org",
      "@type": "WebSite",
      "name": siteName,
      "url": baseUrl,
      "inLanguage": "de-DE",
    })}></script>
    <link href="/pagefind/pagefind-ui.css" rel="stylesheet" />
    {
      import.meta.env.PUBLIC_UMAMI_SCRIPT_URL &&
        import.meta.env.PUBLIC_UMAMI_WEBSITE_ID && (
          <script
            defer
            src={import.meta.env.PUBLIC_UMAMI_SCRIPT_URL}
            data-website-id={import.meta.env.PUBLIC_UMAMI_WEBSITE_ID}
          />
        )
    }
    {
      import.meta.env.PUBLIC_FORMBRICKS_APP_URL &&
        import.meta.env.PUBLIC_FORMBRICKS_ENVIRONMENT_ID && (
          <script
            is:inline
            define:vars={{
              formbricksAppUrl: import.meta.env.PUBLIC_FORMBRICKS_APP_URL,
              formbricksEnvironmentId:
                import.meta.env.PUBLIC_FORMBRICKS_ENVIRONMENT_ID,
            }}
          >
            (function () {
              var appUrl = String(formbricksAppUrl || "").replace(/\/$/, "");
              var environmentId = String(formbricksEnvironmentId || "").trim();
              if (!appUrl || !environmentId) return;
              var t = document.createElement("script");
              t.type = "text/javascript";
              t.async = true;
              t.src = appUrl + "/js/formbricks.umd.cjs";
              var e = document.getElementsByTagName("script")[0];
              if (e && e.parentNode) e.parentNode.insertBefore(t, e);
              setTimeout(function () {
                if (
                  window.formbricks &&
                  typeof window.formbricks.setup === "function"
                ) {
                  window.formbricks.setup({
                    environmentId: environmentId,
                    appUrl: appUrl,
                  });
                }
              }, 500);
            })();
          </script>
        )
    }
    <script
      src="https://analytics.pm86.de/api/script.js"
      data-site-id="ad2858cf2db1"
      defer
    />
  </head>
  <body class="flex min-h-screen flex-col text-zinc-900">
    {
      import.meta.env.DEV && cmsFromCache && (
        <div
          class="sticky top-0 z-50 bg-amber-500 text-amber-950 text-center py-1.5 px-2 text-sm font-medium"
          role="status"
          aria-live="polite"
        >
          CMS nicht erreichbar – Daten werden aus dem Cache (.cache/cms) geladen.
        </div>
      )
    }
    <script id="astro-translations" type="application/json" set:html={safeJsonScriptContent(translations)}></script>
    <script define:vars={{ translations }}>
      try { window.__TRANSLATIONS__ = typeof translations !== "undefined" && translations != null ? translations : {}; } catch (e) {}
    </script>
    <TranslationProvider translations={translations}>
      <Header
        links={headerNavItems}
        socialLinks={socialLinks}
        logoUrl={logoUrl}
        logoSvgHtml={logoSvgHtml}
        translations={translations}
        client:load
      />
      <HeaderOverlay client:load />
      {
        showBannerInLayout &&
          (topBanner != null || topBannerResolvedImages.length > 0) && (
            <TopBanner
              banner={topBanner}
              resolvedImages={topBannerResolvedImages}
              headline={headline}
              subheadline={subheadline}
            />
          )
      }
      <main class="flex-1 min-h-[60em]">
        <div class="container-custom pb-12">
          {resolvedBreadcrumbItems.length > 0 && (
            <Breadcrumbs items={resolvedBreadcrumbItems} client:load />
          )}
          {
            showTitleInContent &&
              (titleHeadlineHtml || titleSubheadlineHtml) && (
                <div class="mb-6 pt-10 pageTitle">
                  {titleHeadlineHtml && (
                    <h1 class="pageTitle" set:html={titleHeadlineHtml} />
                  )}
                  {titleSubheadlineHtml && (
                    <h2 class="pageTitle" set:html={titleSubheadlineHtml} />
                  )}
                </div>
              )
          }
          <slot />
        </div>
      </main>
      <Footer footer={footerData} translations={translations} />
    </TranslationProvider>
    <script src="/pagefind/pagefind-ui.js" is:inline></script>
  </body>
</html>
