b7093b703a
- Palette: gray/zinc/slate/neutral → stein, red → fire, amber → erde, sky → himmel, green → wald - Footer: replaced raw rgb with stein tokens - Radius: unified to rounded-xs across cards, buttons, inputs, pagination - Buttons: .btn-primary/.btn-secondary now font-medium; added secondary - Card hover: -translate-y-0.5 + shadow + wald-300 border - Header active link: wald border-bottom + wald-700 text - Mobile nav: bigger touch targets + wald active accent - Pagination: prev/next text labels + wald-500 active state with separated shape/color classes to avoid Tailwind conflicts - Lead paragraph: scoped .markdown > p:first-child for top-level MarkdownBlock only via [data-block-type="markdown"] - Section dividers: subtle wald-200 gradient between content rows - Global focus-visible ring (wald-500) - Inline hex → palette tokens (Badge amber, Tag custom-color contrast) - Font weights snapped to design system (300/400/500/600/700) - transition-all → transition-colors where only color changes - Removed em-dashes from user-visible templates Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
90 lines
2.4 KiB
Svelte
90 lines
2.4 KiB
Svelte
<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-stein-200 bg-white p-4 text-stein-900",
|
||
},
|
||
{
|
||
variant: "tile",
|
||
layout: "inline",
|
||
class:
|
||
"flex flex-row items-start gap-3 border border-stein-200 bg-white p-4 text-stein-900",
|
||
},
|
||
{
|
||
variant: "tile",
|
||
layout: "post",
|
||
class:
|
||
"flex flex-col gap-0 border border-stein-200 bg-white p-0 text-stein-900",
|
||
},
|
||
],
|
||
defaultVariants: { variant: "tile", layout: "stack" },
|
||
});
|
||
|
||
const cardAsLink = cva("", {
|
||
variants: {
|
||
variant: {
|
||
callout: "cursor-pointer transition-colors no-underline text-inherit hover:bg-wald-100",
|
||
tile: "transition-[transform,box-shadow,border-color] duration-200 no-underline hover:-translate-y-0.5 hover:shadow-md hover:border-wald-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;
|
||
href?: string;
|
||
target?: string;
|
||
rel?: string;
|
||
class?: string;
|
||
} & SurfaceProps = $props();
|
||
|
||
const surface = $derived(cardSurface({ variant, layout }));
|
||
const linkSurface = $derived(
|
||
href ? cardAsLink({ variant: (variant ?? "tile") as CardLinkVariant }) : "",
|
||
);
|
||
</script>
|
||
|
||
{#if href}
|
||
<a {href} {target} {rel} class="{surface} {linkSurface} {className}">
|
||
{@render children?.()}
|
||
</a>
|
||
{:else}
|
||
<div class="{surface} {className}">
|
||
{@render children?.()}
|
||
</div>
|
||
{/if}
|