ui: card-surface utility, rounded corners, calendar polish, banner layout
- Add .card-surface utility (@layer components): rounded-sm border shadow-sm - Card.svelte, CalendarBlock, SearchableTextBlock, BlogOverview use card-surface - OrganisationsBlock: logo h-12 rounded-sm, description style cleanup, pt-1 for hover clip fix - DeadlineBanner: container-custom width constraint, text left-aligned - WindAreaPanel stats: card-surface - CalendarBlock: rounded-sm day headers, past days opacity-20 + diagonal strike - Add .day-past pseudo-element utility for diagonal line Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+26
@@ -10,6 +10,32 @@
|
|||||||
|
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Component Utilities
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
/* Shared card surface: border, background, shadow, radius */
|
||||||
|
.card-surface {
|
||||||
|
@apply rounded-sm border border-stein-200 bg-white shadow-sm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Diagonal strikethrough for past calendar days */
|
||||||
|
.day-past::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 2px;
|
||||||
|
background: linear-gradient(
|
||||||
|
to top right,
|
||||||
|
transparent calc(50% - 0.5px),
|
||||||
|
rgba(0, 0, 0, 0.12) calc(50% - 0.5px),
|
||||||
|
rgba(0, 0, 0, 0.12) calc(50% + 0.5px),
|
||||||
|
transparent calc(50% + 0.5px)
|
||||||
|
);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
Design Tokens – Windwiderstand (01-colors, 02-typography, 06-tokens.json)
|
Design Tokens – Windwiderstand (01-colors, 02-typography, 06-tokens.json)
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|||||||
@@ -235,7 +235,7 @@
|
|||||||
{#each filteredResults as hit}
|
{#each filteredResults as hit}
|
||||||
<a
|
<a
|
||||||
href={searchResultHref(hit.slug)}
|
href={searchResultHref(hit.slug)}
|
||||||
class="flex flex-col overflow-hidden border border-stein-200 bg-white text-stein-900 no-underline transition-colors"
|
class="card-surface flex flex-col overflow-hidden text-stein-900 no-underline transition-colors hover:-translate-y-0.5 hover:shadow-md hover:border-wald-300 transition-[transform,box-shadow,border-color] duration-200"
|
||||||
>
|
>
|
||||||
{#if hit.image}
|
{#if hit.image}
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* tile + post: PostCard – Shell ohne Padding, Medien bündig, Text mit p-4 im Kind.
|
* tile + post: PostCard – Shell ohne Padding, Medien bündig, Text mit p-4 im Kind.
|
||||||
* callout: CTA; layout wird ignoriert.
|
* callout: CTA; layout wird ignoriert.
|
||||||
*/
|
*/
|
||||||
const cardSurface = cva("relative min-w-0 overflow-hidden", {
|
const cardSurface = cva("relative min-w-0 overflow-hidden rounded-sm", {
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
tile: "",
|
tile: "",
|
||||||
@@ -24,20 +24,17 @@
|
|||||||
{
|
{
|
||||||
variant: "tile",
|
variant: "tile",
|
||||||
layout: "stack",
|
layout: "stack",
|
||||||
class:
|
class: "card-surface flex flex-col gap-2 p-4 text-stein-900",
|
||||||
"flex flex-col gap-2 border border-stein-200 bg-white p-4 text-stein-900",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
variant: "tile",
|
variant: "tile",
|
||||||
layout: "inline",
|
layout: "inline",
|
||||||
class:
|
class: "card-surface flex flex-row items-start gap-3 p-4 text-stein-900",
|
||||||
"flex flex-row items-start gap-3 border border-stein-200 bg-white p-4 text-stein-900",
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
variant: "tile",
|
variant: "tile",
|
||||||
layout: "post",
|
layout: "post",
|
||||||
class:
|
class: "card-surface flex flex-col gap-0 p-0 text-stein-900",
|
||||||
"flex flex-col gap-0 border border-stein-200 bg-white p-0 text-stein-900",
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
defaultVariants: { variant: "tile", layout: "stack" },
|
defaultVariants: { variant: "tile", layout: "stack" },
|
||||||
|
|||||||
@@ -536,7 +536,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="{layoutClasses} w-full min-w-0 calendar-block border border-stein-200 overflow-hidden"
|
class="{layoutClasses} w-full min-w-0 calendar-block card-surface overflow-hidden"
|
||||||
data-block="Calendar"
|
data-block="Calendar"
|
||||||
data-block-type="calendar"
|
data-block-type="calendar"
|
||||||
data-block-slug={block._slug}
|
data-block-slug={block._slug}
|
||||||
@@ -1044,7 +1044,7 @@
|
|||||||
<div class="grid grid-cols-7 gap-1.5 text-center text-sm">
|
<div class="grid grid-cols-7 gap-1.5 text-center text-sm">
|
||||||
{#each weekdays as w, i}
|
{#each weekdays as w, i}
|
||||||
<div
|
<div
|
||||||
class="py-1.5 text-xs font-bold rounded-xs {i >= 5
|
class="py-1.5 text-xs font-bold rounded-sm {i >= 5
|
||||||
? 'bg-stein-100/80 text-stein-600'
|
? 'bg-stein-100/80 text-stein-600'
|
||||||
: 'bg-himmel-200/50 text-himmel-800'}"
|
: 'bg-himmel-200/50 text-himmel-800'}"
|
||||||
>
|
>
|
||||||
@@ -1068,6 +1068,7 @@
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="relative h-10 rounded-xs flex flex-col items-center justify-center min-w-0 transition-colors cursor-pointer font-semibold
|
class="relative h-10 rounded-xs flex flex-col items-center justify-center min-w-0 transition-colors cursor-pointer font-semibold
|
||||||
|
{!isFuture ? 'opacity-20 day-past' : ''}
|
||||||
{isCurrentMonth
|
{isCurrentMonth
|
||||||
? 'text-himmel-900'
|
? 'text-himmel-900'
|
||||||
: 'text-himmel-700 opacity-60 hover:opacity-80'}
|
: 'text-himmel-700 opacity-60 hover:opacity-80'}
|
||||||
@@ -1106,6 +1107,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<div
|
<div
|
||||||
class="relative h-10 rounded-xs flex flex-col items-center justify-center min-w-0 cursor-default
|
class="relative h-10 rounded-xs flex flex-col items-center justify-center min-w-0 cursor-default
|
||||||
|
{!isFuture ? 'opacity-20 day-past' : ''}
|
||||||
{isWeekend
|
{isWeekend
|
||||||
? 'bg-stein-100/60'
|
? 'bg-stein-100/60'
|
||||||
: 'bg-himmel-50/50'}
|
: 'bg-himmel-50/50'}
|
||||||
|
|||||||
@@ -116,10 +116,10 @@
|
|||||||
data-block-slug={block._slug}
|
data-block-slug={block._slug}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="gradient-blob-bg flex items-center gap-x-6 bg-gray-50 px-6 py-2.5 sm:px-3.5"
|
class="gradient-blob-bg bg-gray-50 py-2.5"
|
||||||
>
|
>
|
||||||
<span class="hidden flex-1 sm:block" aria-hidden="true"></span>
|
<div class="container-custom flex items-center gap-x-6">
|
||||||
<p class="my-0! text-sm/6 text-gray-900">
|
<p class="my-0! flex-1 text-sm/6 text-gray-900">
|
||||||
{sentence}{#if countdownStr}{sentence ? " · " : ""}<span
|
{sentence}{#if countdownStr}{sentence ? " · " : ""}<span
|
||||||
class="font-semibold">{countdownStr}</span
|
class="font-semibold">{countdownStr}</span
|
||||||
>{/if}{#if href}
|
>{/if}{#if href}
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex flex-1 justify-end">
|
<div class="shrink-0">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => (dismissed = true)}
|
onclick={() => (dismissed = true)}
|
||||||
@@ -151,6 +151,7 @@
|
|||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -64,12 +64,12 @@
|
|||||||
|
|
||||||
{#snippet defaultCard(o: OrganisationEntry, linkUrl: string | undefined, logoField: ReturnType<typeof organisationLogoField>, orgIndex: number)}
|
{#snippet defaultCard(o: OrganisationEntry, linkUrl: string | undefined, logoField: ReturnType<typeof organisationLogoField>, orgIndex: number)}
|
||||||
<Card href={linkUrl} class="h-full">
|
<Card href={linkUrl} class="h-full">
|
||||||
<div class="flex h-11 w-11 shrink-0 items-center justify-center overflow-hidden bg-stein-100">
|
<div class="flex h-12 w-12 shrink-0 items-center justify-center overflow-hidden rounded-sm border border-stein-100 bg-stein-100">
|
||||||
{#if logoField}
|
{#if logoField}
|
||||||
<RustyImage
|
<RustyImage
|
||||||
src={logoField.url}
|
src={logoField.url}
|
||||||
focal={logoField.focal ?? null}
|
focal={logoField.focal ?? null}
|
||||||
width={88}
|
width={96}
|
||||||
aspect="1/1"
|
aspect="1/1"
|
||||||
fit="contain"
|
fit="contain"
|
||||||
quality={85}
|
quality={85}
|
||||||
@@ -98,9 +98,9 @@
|
|||||||
<Badge color={o.badge.color}>{o.badge.label}</Badge>
|
<Badge color={o.badge.color}>{o.badge.label}</Badge>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<h5 class="mb-1 min-w-0 truncate text-sm font-medium leading-tight text-stein-900">{o.name ?? ""}</h5>
|
<h5 class="min-w-0 truncate text-sm font-medium leading-tight text-stein-900">{o.name ?? ""}</h5>
|
||||||
{#if o.description}
|
{#if o.description}
|
||||||
<p class="line-clamp-2 text-xs font-light text-stein-600">{o.description}</p>
|
<p class="line-clamp-2 text-xs text-stein-500">{o.description}</p>
|
||||||
{/if}
|
{/if}
|
||||||
</Card>
|
</Card>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
@@ -140,7 +140,7 @@
|
|||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div
|
||||||
bind:this={scroller}
|
bind:this={scroller}
|
||||||
class="flex gap-4 overflow-x-auto scroll-smooth snap-x snap-mandatory pb-2 [scrollbar-width:thin]"
|
class="flex gap-4 overflow-x-auto scroll-smooth snap-x snap-mandatory pt-1 pb-2 [scrollbar-width:thin]"
|
||||||
>
|
>
|
||||||
{#each orgs as org, orgIndex}
|
{#each orgs as org, orgIndex}
|
||||||
{#if typeof org === "object" && org !== null}
|
{#if typeof org === "object" && org !== null}
|
||||||
|
|||||||
@@ -193,7 +193,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="searchable-text flex flex-col gap-0 border border-stein-200 bg-white shadow-sm overflow-hidden {layoutClasses} {className}"
|
class="searchable-text card-surface flex flex-col gap-0 overflow-hidden {layoutClasses} {className}"
|
||||||
data-block="SearchableText" data-block-type="searchable_text"
|
data-block="SearchableText" data-block-type="searchable_text"
|
||||||
data-block-slug={block._slug}
|
data-block-slug={block._slug}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user