Initial SvelteKit frontend port of windwiderstand.de
Deploy / verify (push) Failing after 32s
Deploy / deploy (push) Has been skipped

Full parity with Astro site: content rows, post/tag routes, pagination,
event badges + OSM map, comments, Live-Search via /api/search-index,
CMS image proxy, RSS, sitemap.

Deploy: Dockerfile + docker-compose.prod.yml + Gitea Actions workflow
to build + push to git.pm86.de registry and ssh-deploy to Contabo.
This commit is contained in:
Peter Meier
2026-04-17 22:01:30 +02:00
parent 852cef0980
commit 2fef91a548
137 changed files with 28585 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
<script lang="ts">
/**
* TopBanner: Fullwidth-Banner mit Bild (über RustyCMS-Transform-API aufgelöst), optionalem Text
* und Titel/Subtitle der aktuellen Page (Markdown).
*/
import { marked } from "marked";
import type { FullwidthBannerEntry } from "$lib/cms";
marked.setOptions({ gfm: true });
interface Props {
banner: FullwidthBannerEntry | null;
resolvedImages?: string[];
/** Headline der Page (Markdown). */
headline?: string;
/** Subheadline der Page (Markdown). */
subheadline?: string;
}
let { banner = null, resolvedImages = [], headline, subheadline }: Props = $props();
const headlineHtml = $derived(
headline?.trim() ? (marked.parseInline(headline) as string) : "",
);
const subheadlineHtml = $derived(
subheadline?.trim() ? (marked.parseInline(subheadline) as string) : "",
);
const hasImage = $derived(resolvedImages.length > 0 && Boolean(resolvedImages[0]?.trim()));
const hasText = $derived(banner?.text != null && banner.text !== "");
const hasPageTitle = $derived((headline != null && headline !== "") || (subheadline != null && subheadline !== ""));
const showBanner = $derived(hasImage || hasText || hasPageTitle);
</script>
{#if showBanner}
<div class="w-full">
{#if hasImage}
<div class="w-full overflow-hidden relative flex justify-center items-center shadow-lg border-b border-white">
<img
src={resolvedImages[0]}
alt={banner?.headline ?? headline ?? ""}
class="w-full object-cover max-h-[400px] lg:max-h-[600px] max-w-[1920px] aspect-square sm:aspect-video lg:aspect-24/9"
width={1920}
height={600}
loading="eager"
fetchpriority="high"
/>
{#if hasPageTitle}
<div class="absolute inset-0 flex items-center justify-start ">
<div class="container-custom mx-auto px-6 relative">
{#if headlineHtml}
<h1 class="bg-red-400/70 inline-block py-1 px-2 -ml-2 backdrop-blur">{@html headlineHtml}</h1>
{/if}
<div></div>
{#if subheadlineHtml}
<h2 class="bg-white/50 inline-block py-1 px-2 -ml-2 backdrop-blur font-light! text-xl!">{@html subheadlineHtml}</h2>
{/if}
</div>
</div>
{/if}
</div>
{:else if hasPageTitle}
<div class="border-b border-zinc-200 container mx-auto px-6 py-4">
{#if headlineHtml}
<h1 class="text-2xl font-bold text-zinc-900">{@html headlineHtml}</h1>
{/if}
{#if subheadlineHtml}
<h2 class="text-lg text-zinc-600 mt-1">{@html subheadlineHtml}</h2>
{/if}
</div>
{/if}
{#if hasText}
<div class="w-full bg-green-700 text-white text-center py-2 px-4">
<div class="container mx-auto">
<div class="text-sm font-medium">{banner!.text}</div>
</div>
</div>
{/if}
</div>
{/if}