feat(calendar-compact): polish + global not-prose opt-out support
CalendarCompact: - denser layout (smaller padding/font/badge), header icon size-8 - icon stein-900 (black), subtle wald gradient background - rounded-sm to match design tokens (was rounded-lg) - list items link to linkTo + "#event-<slug>" anchor; <svelte:element> falls back to div when no linkTo is set - not-prose on root so global content margins/list/link rules don't apply to the card subtree blog-utils.resolveCalendarBlocks: - when items array is empty, fall back to the full calendar_item pool (both default and compact variant get this) — saves editors from re-listing items on every page. app.css: add `:where(:not(.not-prose *))` to .content p/h1-h4, main a (link colour + underline), main ul/ol so subtrees marked not-prose stop inheriting the global prose-like defaults. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -62,45 +62,53 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="{layoutClasses} w-full min-w-0 card-surface overflow-hidden rounded-lg border border-stein-200 bg-white"
|
||||
class="not-prose {layoutClasses} w-full min-w-0 card-surface overflow-hidden rounded-sm border border-stein-200 bg-gradient-to-br from-wald-50/60 via-white to-white"
|
||||
data-block="CalendarCompact"
|
||||
data-block-type="calendar"
|
||||
data-block-variant="compact"
|
||||
data-block-slug={block._slug}
|
||||
>
|
||||
<header class="flex items-center gap-2 border-b border-stein-100 px-4 py-3 sm:px-5">
|
||||
<Icon icon="mdi:calendar-month-outline" class="size-5 text-wald-600" aria-hidden="true" />
|
||||
<h2 class="text-base font-semibold text-stein-800">
|
||||
<header class="flex items-center gap-2 border-b border-stein-100 px-3 py-2">
|
||||
<Icon icon="mdi:calendar-month-outline" class="size-8 shrink-0 text-stein-900" aria-hidden="true" />
|
||||
<h2 class="text-sm font-semibold leading-none text-stein-800">
|
||||
{block.title ?? t(T.calendar_next_events)}
|
||||
</h2>
|
||||
</header>
|
||||
|
||||
{#if upcoming.length === 0}
|
||||
<p class="px-4 py-6 text-center text-sm text-stein-500 sm:px-5">
|
||||
<p class="px-3 py-4 text-center text-xs text-stein-500">
|
||||
{t(T.calendar_no_future_events)}
|
||||
</p>
|
||||
{:else}
|
||||
<ul class="divide-y divide-stein-100">
|
||||
{#each upcoming as { it, start } (it._slug ?? it.title)}
|
||||
{@const timeStr = fmtTime(start)}
|
||||
<li class="flex items-start gap-3 px-4 py-3 sm:px-5">
|
||||
<div class="flex w-14 shrink-0 flex-col items-center rounded bg-wald-50 px-1 py-1.5 text-wald-700">
|
||||
<span class="text-[0.65rem] font-semibold uppercase leading-none">
|
||||
{start.toLocaleDateString("de-DE", { month: "short" }).replace(".", "")}
|
||||
</span>
|
||||
<span class="text-lg font-bold tabular-nums leading-none">
|
||||
{start.getDate()}
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="truncate text-sm font-semibold text-stein-800">{it.title ?? t(T.calendar_untitled)}</p>
|
||||
<p class="mt-0.5 text-xs text-stein-500">
|
||||
{fmtDate(start)}{timeStr ? ` · ${timeStr}` : ""}
|
||||
{#if it.location}
|
||||
<span class="ml-1">· {typeof it.location === "string" ? it.location : (it.location as { text?: string })?.text ?? ""}</span>
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
{@const base = linkHref()}
|
||||
{@const itemHref = base && it._slug ? `${base}#event-${it._slug}` : null}
|
||||
<li>
|
||||
<svelte:element
|
||||
this={itemHref ? "a" : "div"}
|
||||
href={itemHref ?? undefined}
|
||||
class="flex items-start gap-2.5 px-3 py-2 {itemHref ? 'transition-colors hover:bg-wald-50/40' : ''}"
|
||||
>
|
||||
<div class="flex w-11 shrink-0 flex-col items-center rounded-sm bg-wald-50 px-1 py-1 text-wald-700">
|
||||
<span class="text-[0.6rem] font-semibold uppercase leading-none">
|
||||
{start.toLocaleDateString("de-DE", { month: "short" }).replace(".", "")}
|
||||
</span>
|
||||
<span class="text-base font-bold tabular-nums leading-none mt-0.5">
|
||||
{start.getDate()}
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<p class="truncate text-xs font-semibold text-stein-800">{it.title ?? t(T.calendar_untitled)}</p>
|
||||
<p class="mt-0.5 text-[0.7rem] text-stein-500">
|
||||
{fmtDate(start)}{timeStr ? ` · ${timeStr}` : ""}
|
||||
{#if it.location}
|
||||
<span class="ml-1">· {typeof it.location === "string" ? it.location : (it.location as { text?: string })?.text ?? ""}</span>
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
</svelte:element>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
@@ -109,10 +117,10 @@
|
||||
{#if linkHref()}
|
||||
<a
|
||||
href={linkHref()}
|
||||
class="flex items-center justify-center gap-1 border-t border-stein-100 bg-stein-50 px-4 py-2.5 text-sm font-medium text-wald-700 hover:bg-wald-50"
|
||||
class="flex items-center justify-center gap-1 border-t border-stein-100 bg-stein-50 px-3 py-1.5 text-xs font-medium text-wald-700 hover:bg-wald-50"
|
||||
>
|
||||
{t(T.calendar_all_upcoming)}
|
||||
<Icon icon="mdi:arrow-right" class="size-4" aria-hidden="true" />
|
||||
<Icon icon="mdi:arrow-right" class="size-3.5" aria-hidden="true" />
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user