feat(section-grid): InfoCard + SectionGrid als CMS-Block
Deploy / verify (push) Successful in 2m27s
Deploy / deploy (push) Successful in 1m49s

Neuer section_grid-Block (SectionHeader + Card-Grid aus info_card-Refs) +
info_card-Collection. SectionGrid/InfoCard-Komponenten, BlockRenderer-Case,
content_layout erlaubt section_grid in Rows. SectionHeader.title jetzt optional
(Kicker-only-Header).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Peter Meier
2026-07-12 09:37:05 +02:00
parent 7c7538a22c
commit 3878a2ed26
8 changed files with 352 additions and 6 deletions
+61
View File
@@ -0,0 +1,61 @@
<script lang="ts">
/**
* InfoCard — Icon/Bild + Titel + Beschreibung + optionaler Link.
* Wiederverwendbare Kachel für Sektions-Grids (siehe SectionGrid).
*
* `icon` ist entweder ein Iconify-String ("mdi:email") ODER eine Bild-URL
* (https://… oder /…) — wird automatisch erkannt.
*/
import Icon from "@iconify/svelte";
import "$lib/iconify-offline";
import RustyImage from "$lib/components/RustyImage.svelte";
let {
icon = undefined,
title,
description = undefined,
linkLabel = undefined,
linkHref = undefined,
external = false,
}: {
icon?: string;
title: string;
description?: string;
linkLabel?: string;
linkHref?: string;
external?: boolean;
} = $props();
// Bild-URL vs Iconify-String unterscheiden.
const isImage = $derived(!!icon && (/^https?:\/\//.test(icon) || icon.startsWith("/")));
const hasLink = $derived(!!linkLabel && !!linkHref);
</script>
<div class="flex h-full flex-col rounded-lg border border-stein-200 bg-white p-6">
{#if icon}
<div class="flex size-11 items-center justify-center overflow-hidden rounded-full bg-wald-50 text-wald-700">
{#if isImage}
<RustyImage src={icon} width={44} aspect="1/1" alt="" class="size-full object-cover" />
{:else}
<Icon icon={icon} class="size-5" aria-hidden="true" />
{/if}
</div>
{/if}
<h3 class="mt-4 text-lg font-semibold text-stein-900">{title}</h3>
{#if description}
<p class="mt-1 text-sm text-stein-500">{description}</p>
{/if}
{#if hasLink}
<a
href={linkHref}
target={external ? "_blank" : undefined}
rel={external ? "noopener noreferrer" : undefined}
class="mt-4 inline-flex items-center gap-1.5 text-[15px] font-semibold text-himmel-600 no-underline hover:text-himmel-700"
>
{linkLabel}
<svg class="size-4" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</a>
{/if}
</div>