feat: add class-variance-authority for card styling and enhance color palettes
Deploy / verify (push) Failing after 1m40s
Deploy / deploy (push) Has been skipped

- Introduced `class-variance-authority` to manage card component styles, allowing for flexible variant and layout options.
- Added a new color palette for "Fire" to the CSS for improved theming.
- Updated `Card` and `PostCard` components to utilize the new styling system, enhancing visual consistency and responsiveness.
- Refined layout and styling in various components for better user experience.
This commit is contained in:
Peter Meier
2026-04-20 22:09:43 +02:00
parent a18c0a8cf7
commit d327798ce6
9 changed files with 191 additions and 119 deletions
+1
View File
@@ -29,6 +29,7 @@
"@fontsource/inter": "^5.2.8",
"@iconify/svelte": "^5.2.1",
"blurhash": "^2.0.5",
"class-variance-authority": "^0.7.1",
"marked": "^17.0.2",
"sharp": "^0.34.5"
},
+13
View File
@@ -51,6 +51,19 @@
--color-himmel-800: #1a2c36;
--color-himmel-900: #0e181e;
/* Palette: Fire (Tertiary) */
--color-fire-50: #fdf2f1;
--color-fire-100: #fbe5e3;
--color-fire-200: #f7c9c5;
--color-fire-300: #f2a8a2;
--color-fire-400: #eb8078;
--color-fire-500: #e35651;
--color-fire-600: #d93d36;
--color-fire-700: #c82e27;
--color-fire-800: #b5231e;
--color-fire-900: #981b18;
--color-fire-950: #5d0f0b;
/* Palette: Stein (Neutrals) */
--color-stein-0: #ffffff;
--color-stein-50: #f7f8f7;
+63 -6
View File
@@ -1,11 +1,68 @@
<script lang="ts">
import type { Snippet } from "svelte";
import { cva, type VariantProps } from "class-variance-authority";
/**
* tile + stack/inline: Org-Karten (Padding im Shell).
* tile + post: PostCard Shell ohne Padding, Medien bündig, Text mit p-4 im Kind.
* callout: CTA; layout wird ignoriert.
*/
const cardSurface = cva("relative min-w-0 overflow-hidden", {
variants: {
variant: {
tile: "",
callout:
"flex flex-col gap-1.5 border border-dashed border-wald-300 bg-wald-50 p-3",
},
layout: {
stack: "",
inline: "",
post: "",
},
},
compoundVariants: [
{
variant: "tile",
layout: "stack",
class:
"flex flex-col gap-2 border border-gray-200 bg-white p-4 text-slate-950",
},
{
variant: "tile",
layout: "inline",
class:
"flex flex-row items-start gap-3 border border-gray-200 bg-white p-4 text-slate-950",
},
{
variant: "tile",
layout: "post",
class:
"flex flex-col gap-0 border border-gray-200 bg-white p-0 text-slate-950",
},
],
defaultVariants: { variant: "tile", layout: "stack" },
});
const cardAsLink = cva("", {
variants: {
variant: {
callout: "cursor-pointer transition-all no-underline text-inherit",
tile: "transition-all no-underline hover:border-gray-300",
},
},
defaultVariants: { variant: "tile" },
});
type SurfaceProps = VariantProps<typeof cardSurface>;
type CardLinkVariant = NonNullable<SurfaceProps["variant"]>;
let {
children,
href,
target,
rel,
variant = "tile",
layout = "stack",
class: className = "",
}: {
children?: Snippet;
@@ -13,20 +70,20 @@
target?: string;
rel?: string;
class?: string;
} = $props();
} & SurfaceProps = $props();
const base = "relative flex flex-col gap-2 rounded-lg border border-stein-200 bg-white p-4 shadow-sm min-w-0 overflow-hidden";
const interactive = $derived(
href ? "hover:border-stein-300 hover:shadow-md transition-all no-underline text-inherit" : "",
const surface = $derived(cardSurface({ variant, layout }));
const linkSurface = $derived(
href ? cardAsLink({ variant: (variant ?? "tile") as CardLinkVariant }) : "",
);
</script>
{#if href}
<a {href} {target} {rel} class="{base} {interactive} {className}">
<a {href} {target} {rel} class="{surface} {linkSurface} {className}">
{@render children?.()}
</a>
{:else}
<div class="{base} {className}">
<div class="{surface} {className}">
{@render children?.()}
</div>
{/if}
+1 -1
View File
@@ -121,7 +121,7 @@
{link.label}
</a>
{/each}
<div><span class="opacity-20">|</span></div>
<div class="w-1 h-4"></div>
{#each socialLinks as social}
<a
href={social.href}
+6 -4
View File
@@ -3,6 +3,7 @@
import PostMeta from "./PostMeta.svelte";
import EventBadges from "./EventBadges.svelte";
import RustyImage from "./RustyImage.svelte";
import Card from "./Card.svelte";
type PostWithImage = PostEntry & {
_resolvedImageUrl?: string;
@@ -45,9 +46,10 @@
);
</script>
<a
href={href}
class="transition-all flex flex-col text-slate-950 no-underline overflow-hidden border border-gray-200 bg-white relative {isPastEvent ? 'opacity-70 grayscale' : ''}"
<Card
{href}
layout="post"
class={isPastEvent ? "opacity-70 grayscale" : ""}
>
<div class="relative aspect-3/2 w-full overflow-hidden bg-gray-100">
{#if rawImg}
@@ -110,4 +112,4 @@
{/if}
</div>
</div>
</a>
</Card>
+1 -1
View File
@@ -99,7 +99,7 @@
<div class="w-full">
{#if hasImage}
<div
class="w-full overflow-hidden relative flex justify-center items-center shadow-lg border-b border-white bg-zinc-200"
class="w-full overflow-hidden relative flex justify-center items-center shadow-lg bg-zinc-200"
style={wrapperStyle}
>
{#if hasResponsive && responsive}
@@ -84,7 +84,7 @@
? "bg-amber-100 text-amber-900"
: variant === "info"
? "bg-sky-100 text-sky-900"
: "bg-wald-100 text-wald-900",
: "bg-wald-500 text-wald-50",
);
const iconName = $derived(
variant === "urgent" ? "mdi:alert-circle" : "mdi:calendar-clock",
@@ -99,30 +99,35 @@
data-block-slug={block._slug}
>
{#snippet inner()}
<div class="container-custom flex flex-wrap sm:flex-nowrap items-center gap-x-2 gap-y-1 px-4 py-1.5 text-xs sm:text-sm">
<div class="container-custom flex flex-wrap sm:flex-nowrap items-center gap-x-2 gap-y-1 px-4 py-2 text-xs sm:text-sm">
{#if dateStr}
<span class="inline-flex items-center gap-1.5 rounded-md bg-white/70 px-2 py-0.5 text-sm sm:text-base font-bold whitespace-nowrap shrink-0">
<Icon icon={iconName} class="size-4 shrink-0" aria-hidden="true" />
{dateStr}
<span class="inline-flex items-center rounded-md bg-white/50 text-wald-900 px-2 py-0.5 text-sm sm:text-base font-bold whitespace-nowrap shrink-0">
<span class="inline-flex items-center gap-1.5">
<Icon icon={iconName} class="size-4 shrink-0" aria-hidden="true" />
{dateStr}
</span>
{#if countdownStr}
<span class="ml-1 rounded-full bg-black/80 text-white px-1.5 py-0 text-[0.6rem] font-bold uppercase tracking-wide">
<span
class="ml-0 inline-flex min-w-0 max-w-0 scale-[0.96] items-center overflow-hidden whitespace-nowrap rounded-md border border-transparent py-0.5 text-[0.6rem] font-semibold uppercase tracking-wide opacity-0 transition-[max-width,margin,opacity,transform,padding,border-color] duration-200 ease-out group-hover:ml-2 group-hover:max-w-48 group-hover:border-wald-900 group-hover:px-2 group-hover:opacity-100 group-hover:scale-100 group-focus-within:ml-2 group-focus-within:max-w-48 group-focus-within:border-wald-900 group-focus-within:px-2 group-focus-within:opacity-100 group-focus-within:scale-100"
>
{countdownStr}
</span>
{/if}
</span>
{:else}
<Icon icon={iconName} class="size-4 shrink-0" aria-hidden="true" />
{#if countdownStr}
<span class="rounded-full bg-white/60 px-2 py-0.5 text-xs font-semibold uppercase tracking-wide whitespace-nowrap shrink-0">
{countdownStr}
</span>
{/if}
<span class="inline-flex items-center gap-0 shrink-0">
<Icon icon={iconName} class="size-4 shrink-0" aria-hidden="true" />
{#if countdownStr}
<span
class="ml-0 inline-flex min-w-0 max-w-0 shrink-0 scale-[0.96] items-center overflow-hidden whitespace-nowrap rounded-full px-0 py-0.5 text-xs font-semibold uppercase tracking-wide opacity-0 transition-[max-width,margin,opacity,transform,padding] duration-200 ease-out group-hover:ml-2 group-hover:max-w-48 group-hover:px-2 group-hover:opacity-100 group-hover:scale-100 group-focus-within:ml-2 group-focus-within:max-w-48 group-focus-within:px-2 group-focus-within:opacity-100 group-focus-within:scale-100"
>
{countdownStr}
</span>
{/if}
</span>
{/if}
{#if text}
<span class="min-w-0 wrap-break-word line-clamp-2 sm:line-clamp-1">{text}</span>
{/if}
{#if href}
<Icon icon="mdi:arrow-right" class="size-4 shrink-0 ml-auto" aria-hidden="true" />
<span class="min-w-0 wrap-break-word line-clamp-2 sm:line-clamp-1 font-semibold text-shadow-sm">{text}</span>
{/if}
</div>
{/snippet}
@@ -131,12 +136,12 @@
href={href}
target={newTab ? "_blank" : undefined}
rel={newTab ? "noopener noreferrer" : undefined}
class="block no-underline text-inherit hover:no-underline transition-all hover:brightness-95 {variantClasses}"
class="group block no-underline text-inherit hover:no-underline transition-all hover:brightness-95 {variantClasses}"
>
{@render inner()}
</a>
{:else}
<div class="{variantClasses}">
<div class="group {variantClasses}">
{@render inner()}
</div>
{/if}
@@ -56,10 +56,6 @@
)
);
const addOrganisationCardClass = $derived(
`border-dashed border-wald-300 bg-wald-50! p-3! gap-1.5!${addOrganisationCtaLink ? " cursor-pointer" : ""}`,
);
let scroller: HTMLDivElement | undefined = $state();
function scrollByPage(dir: 1 | -1) {
if (!scroller) return;
@@ -68,8 +64,8 @@
</script>
{#snippet defaultCard(o: OrganisationEntry, linkUrl: string | undefined, logoField: ReturnType<typeof organisationLogoField>, orgIndex: number)}
<Card href={linkUrl} class="p-3! gap-1.5! h-full">
<div class="h-11 w-11 rounded-md border border-stein-100 bg-stein-50 flex items-center justify-center overflow-hidden shrink-0">
<Card href={linkUrl} class="h-full">
<div class="flex h-11 w-11 shrink-0 items-center justify-center overflow-hidden bg-gray-100">
{#if logoField}
<RustyImage
src={logoField.url}
@@ -84,7 +80,7 @@
/>
{:else}
{@const fishMaskId = `org-logo-fallback-mask-${orgIndex}`}
<svg class="h-8 w-8 text-stein-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" fill="currentColor" aria-hidden="true">
<svg class="h-8 w-8 text-gray-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" fill="currentColor" aria-hidden="true">
<defs>
<mask id={fishMaskId}>
<g fill="none">
@@ -103,19 +99,20 @@
<Badge color={o.badge.color}>{o.badge.label}</Badge>
</div>
{/if}
<h5 class="min-w-0 text-sm font-semibold leading-snug text-stein-900 truncate">{o.name ?? ""}</h5>
<h5 class="mb-1 min-w-0 truncate text-sm font-medium leading-tight text-slate-950">{o.name ?? ""}</h5>
{#if o.description}
<p class="text-xs text-stein-600 line-clamp-2">{o.description}</p>
<p class="line-clamp-2 text-xs font-light text-slate-600">{o.description}</p>
{/if}
</Card>
{/snippet}
{#snippet ctaCard()}
<Card
variant="callout"
href={addOrganisationCtaLink?.url}
target={addOrganisationCtaLink?.newTab ? "_blank" : undefined}
rel={addOrganisationCtaLink?.newTab ? "noopener noreferrer" : undefined}
class="{addOrganisationCardClass} h-full"
class="h-full"
>
{#if block.addOrganisationTitle}
<h5 class="text-sm font-semibold text-wald-800 leading-snug">{block.addOrganisationTitle}</h5>
@@ -138,7 +135,7 @@
<div class="relative">
<div
bind:this={scroller}
class="flex gap-3 overflow-x-auto scroll-smooth snap-x snap-mandatory pb-2 -mx-2 px-2 [scrollbar-width:thin]"
class="flex gap-4 overflow-x-auto scroll-smooth snap-x snap-mandatory pb-2 [scrollbar-width:thin]"
>
{#each orgs as org, orgIndex}
{#if typeof org === "object" && org !== null}
@@ -151,7 +148,9 @@
? o.link.url.trim()
: undefined}
{@const logoField = organisationLogoField(o)}
<div class="shrink-0 snap-start basis-1/2 lg:basis-1/3">
<div
class="shrink-0 snap-start w-[calc((100%-1rem)/2)] lg:w-[calc((100%-2rem)/3)]"
>
{@render defaultCard(o, linkUrl, logoField, orgIndex)}
</div>
{/if}
@@ -177,27 +176,16 @@
{/if}
</div>
{#if showAddOrganisationCard}
<div class="mt-4 rounded-md border border-dashed border-wald-300 bg-wald-50 p-3 text-sm text-wald-800">
{#if block.addOrganisationTitle}
<div class="font-semibold">{block.addOrganisationTitle}</div>
{/if}
{#if ctaHtml}
<div class="markdown text-xs text-wald-700 [&>p]:mb-0">{@html ctaHtml}</div>
{/if}
{#if addOrganisationCtaLink}
<a
href={addOrganisationCtaLink.url}
target={addOrganisationCtaLink.newTab ? "_blank" : undefined}
rel={addOrganisationCtaLink.newTab ? "noopener noreferrer" : undefined}
class="mt-1 inline-block font-medium underline-offset-2 hover:underline"
>
{addOrganisationCtaLink.linkName}
</a>
{/if}
<div class="mt-2 min-w-0">
{@render ctaCard()}
</div>
{/if}
{:else}
<div class={compact ? "grid gap-2 sm:grid-cols-2 lg:grid-cols-3" : "grid gap-4 sm:grid-cols-2 lg:grid-cols-3"}>
<div
class={compact
? "grid grid-cols-1 gap-2 md:grid-cols-2 lg:grid-cols-3"
: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3"}
>
{#each orgs as org, orgIndex}
{#if typeof org === "object" && org !== null}
{@const o = org as OrganisationEntry}
@@ -210,8 +198,8 @@
: undefined}
{@const logoField = organisationLogoField(o)}
{#if compact}
<Card href={linkUrl} class="flex! flex-row! items-start! gap-3! p-3! gap-y-0!">
<div class="h-10 w-10 rounded-md border border-stein-100 bg-stein-50 flex items-center justify-center overflow-hidden shrink-0">
<Card href={linkUrl} layout="inline" class="h-full">
<div class="flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden bg-gray-100">
{#if logoField}
<RustyImage
src={logoField.url}
@@ -226,7 +214,7 @@
/>
{:else}
{@const fishMaskId = `org-logo-fallback-mask-c-${orgIndex}`}
<svg class="h-7 w-7 text-stein-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" fill="currentColor" aria-hidden="true">
<svg class="h-7 w-7 text-gray-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" fill="currentColor" aria-hidden="true">
<defs>
<mask id={fishMaskId}>
<g fill="none">
@@ -240,10 +228,10 @@
</svg>
{/if}
</div>
<div class="min-w-0 flex-1 flex flex-col gap-0.5">
<h5 class="text-sm font-semibold text-stein-900 leading-snug">{o.name ?? ""}</h5>
<div class="flex min-w-0 flex-1 flex-col gap-0.5">
<h5 class="text-sm font-medium leading-tight text-slate-950">{o.name ?? ""}</h5>
{#if o.description}
<p class="text-xs text-stein-600 line-clamp-2">{o.description}</p>
<p class="line-clamp-2 text-xs font-light text-slate-600">{o.description}</p>
{/if}
</div>
</Card>
+59 -53
View File
@@ -17,25 +17,24 @@
integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==
"@emnapi/core@^1.7.1", "@emnapi/core@^1.8.1":
version "1.8.1"
version "1.10.0"
resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.10.0.tgz#380ccc8f2412ea22d1d972df7f8ee23a3b9c7467"
integrity sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==
dependencies:
"@emnapi/wasi-threads" "1.1.0"
"@emnapi/wasi-threads" "1.2.1"
tslib "^2.4.0"
"@emnapi/runtime@^1.7.0":
"@emnapi/runtime@^1.7.0", "@emnapi/runtime@^1.7.1", "@emnapi/runtime@^1.8.1":
version "1.10.0"
resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz"
integrity sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==
dependencies:
tslib "^2.4.0"
"@emnapi/runtime@^1.7.1", "@emnapi/runtime@^1.8.1":
version "1.8.1"
dependencies:
tslib "^2.4.0"
"@emnapi/wasi-threads@^1.1.0", "@emnapi/wasi-threads@1.1.0":
version "1.1.0"
"@emnapi/wasi-threads@1.2.1", "@emnapi/wasi-threads@^1.1.0":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz#28fed21a1ba1ce797c44a070abc94d42f3ae8548"
integrity sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==
dependencies:
tslib "^2.4.0"
@@ -44,16 +43,16 @@
resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz"
integrity sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==
"@esbuild/android-arm@0.25.12":
version "0.25.12"
resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz"
integrity sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==
"@esbuild/android-arm64@0.25.12":
version "0.25.12"
resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz"
integrity sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==
"@esbuild/android-arm@0.25.12":
version "0.25.12"
resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz"
integrity sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==
"@esbuild/android-x64@0.25.12":
version "0.25.12"
resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz"
@@ -79,16 +78,16 @@
resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz"
integrity sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==
"@esbuild/linux-arm@0.25.12":
version "0.25.12"
resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz"
integrity sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==
"@esbuild/linux-arm64@0.25.12":
version "0.25.12"
resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz"
integrity sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==
"@esbuild/linux-arm@0.25.12":
version "0.25.12"
resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz"
integrity sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==
"@esbuild/linux-ia32@0.25.12":
version "0.25.12"
resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz"
@@ -232,16 +231,16 @@
resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz"
integrity sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==
"@img/sharp-libvips-linux-arm@1.2.4":
version "1.2.4"
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz"
integrity sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==
"@img/sharp-libvips-linux-arm64@1.2.4":
version "1.2.4"
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz"
integrity sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==
"@img/sharp-libvips-linux-arm@1.2.4":
version "1.2.4"
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz"
integrity sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==
"@img/sharp-libvips-linux-ppc64@1.2.4":
version "1.2.4"
resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz"
@@ -272,13 +271,6 @@
resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz"
integrity sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==
"@img/sharp-linux-arm@0.34.5":
version "0.34.5"
resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz"
integrity sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==
optionalDependencies:
"@img/sharp-libvips-linux-arm" "1.2.4"
"@img/sharp-linux-arm64@0.34.5":
version "0.34.5"
resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz"
@@ -286,6 +278,13 @@
optionalDependencies:
"@img/sharp-libvips-linux-arm64" "1.2.4"
"@img/sharp-linux-arm@0.34.5":
version "0.34.5"
resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz"
integrity sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==
optionalDependencies:
"@img/sharp-libvips-linux-arm" "1.2.4"
"@img/sharp-linux-ppc64@0.34.5":
version "0.34.5"
resolved "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz"
@@ -613,7 +612,7 @@
"@rollup/plugin-node-resolve" "^16.0.0"
rollup "^4.59.0"
"@sveltejs/kit@^2.21.4", "@sveltejs/kit@^2.4.0":
"@sveltejs/kit@^2.21.4":
version "2.55.0"
resolved "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.55.0.tgz"
integrity sha512-MdFRjevVxmAknf2NbaUkDF16jSIzXMWd4Nfah0Qp8TtQVoSp3bV4jKt8mX7z7qTUTWvgSaxtR0EG5WJf53gcuA==
@@ -638,7 +637,7 @@
dependencies:
debug "^4.3.7"
"@sveltejs/vite-plugin-svelte@^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "@sveltejs/vite-plugin-svelte@^5.0.0", "@sveltejs/vite-plugin-svelte@^5.0.3":
"@sveltejs/vite-plugin-svelte@^5.0.3":
version "5.1.1"
resolved "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.1.1.tgz"
integrity sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ==
@@ -769,12 +768,12 @@
resolved "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz"
integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==
"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.5", "@types/estree@^1.0.6", "@types/estree@1.0.8":
"@types/estree@*", "@types/estree@1.0.8", "@types/estree@^1.0.0", "@types/estree@^1.0.5", "@types/estree@^1.0.6":
version "1.0.8"
resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz"
integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
"@types/node@^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node@^22.10.0":
"@types/node@^22.10.0":
version "22.19.15"
resolved "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz"
integrity sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==
@@ -796,7 +795,7 @@
resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz"
integrity sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==
acorn@^8.12.1, acorn@^8.14.1, acorn@^8.9.0:
acorn@^8.12.1, acorn@^8.14.1:
version "8.16.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz"
integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==
@@ -848,6 +847,13 @@ change-case@^5.4.4:
resolved "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz"
integrity sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==
class-variance-authority@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.1.tgz#4008a798a0e4553a781a57ac5177c9fb5d043787"
integrity sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==
dependencies:
clsx "^2.1.1"
clsx@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz"
@@ -868,7 +874,7 @@ cookie@^0.6.0:
resolved "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
debug@^4.3.7, debug@^4.4.1, debug@4:
debug@4, debug@^4.3.7, debug@^4.4.1:
version "4.4.3"
resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz"
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
@@ -1005,13 +1011,6 @@ is-module@^1.0.0:
resolved "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz"
integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==
is-reference@^3.0.3:
version "3.0.3"
resolved "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz"
integrity sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==
dependencies:
"@types/estree" "^1.0.6"
is-reference@1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz"
@@ -1019,7 +1018,14 @@ is-reference@1.2.1:
dependencies:
"@types/estree" "*"
jiti@^2.6.1, jiti@>=1.21.0:
is-reference@^3.0.3:
version "3.0.3"
resolved "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz"
integrity sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==
dependencies:
"@types/estree" "^1.0.6"
jiti@^2.6.1:
version "2.6.1"
resolved "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz"
integrity sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==
@@ -1106,7 +1112,7 @@ lightningcss-win32-x64-msvc@1.31.1:
resolved "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz"
integrity sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==
lightningcss@^1.21.0, lightningcss@1.31.1:
lightningcss@1.31.1:
version "1.31.1"
resolved "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz"
integrity sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==
@@ -1195,7 +1201,7 @@ picocolors@^1.1.1:
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
"picomatch@^3 || ^4", picomatch@^4.0.2, picomatch@^4.0.3:
picomatch@^4.0.2, picomatch@^4.0.3:
version "4.0.3"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz"
integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==
@@ -1228,7 +1234,7 @@ resolve@^1.22.1:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0, rollup@^2.68.0||^3.0.0||^4.0.0, rollup@^2.78.0||^3.0.0||^4.0.0, rollup@^4.34.9, rollup@^4.59.0:
rollup@^4.34.9, rollup@^4.59.0:
version "4.59.0"
resolved "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz"
integrity sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==
@@ -1330,7 +1336,7 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
"svelte@^4.0.0 || ^5.0.0-next.0", svelte@^5.0.0, svelte@^5.28.2, svelte@>5.0.0:
svelte@^5.28.2:
version "5.53.12"
resolved "https://registry.npmjs.org/svelte/-/svelte-5.53.12.tgz"
integrity sha512-4x/uk4rQe/d7RhfvS8wemTfNjQ0bJbKvamIzRBfTe2eHHjzBZ7PZicUQrC2ryj83xxEacfA1zHKd1ephD1tAxA==
@@ -1352,7 +1358,7 @@ supports-preserve-symlinks-flag@^1.0.0:
magic-string "^0.30.11"
zimmerframe "^1.1.2"
tailwindcss@^4.1.18, tailwindcss@4.2.1:
tailwindcss@4.2.1, tailwindcss@^4.1.18:
version "4.2.1"
resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz"
integrity sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==
@@ -1385,7 +1391,7 @@ type-fest@^4.39.1:
resolved "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz"
integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==
typescript@^5.3.3, typescript@^5.9.3, typescript@^5.x:
typescript@^5.9.3:
version "5.9.3"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz"
integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
@@ -1400,7 +1406,7 @@ uri-js-replace@^1.0.1:
resolved "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz"
integrity sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==
"vite@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-beta.0", "vite@^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0", "vite@^5.2.0 || ^6 || ^7", vite@^6.0.0, vite@^6.3.5:
vite@^6.3.5:
version "6.4.1"
resolved "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz"
integrity sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==