feat(calendar): grid color polish, month header layout, direct event links
- month label left + larger, prev/next arrows grouped right - weekday headers colored (himmel/stein by weekday/weekend) - day cells colored by weekday/weekend + event state - event anchor IDs, onDestroy SSR fix, ImageModal component - copy link button, action buttons always show text Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -11,10 +11,7 @@
|
|||||||
mapsUrl,
|
mapsUrl,
|
||||||
type CalendarItemICS,
|
type CalendarItemICS,
|
||||||
} from "$lib/calendar-ics";
|
} from "$lib/calendar-ics";
|
||||||
import {
|
import { getCmsImageUrl, extractCmsImageField } from "$lib/rusty-image";
|
||||||
getCmsImageUrl,
|
|
||||||
extractCmsImageField,
|
|
||||||
} from "$lib/rusty-image";
|
|
||||||
import "$lib/iconify-offline";
|
import "$lib/iconify-offline";
|
||||||
import Icon from "@iconify/svelte";
|
import Icon from "@iconify/svelte";
|
||||||
import ImageModal from "$lib/components/ImageModal.svelte";
|
import ImageModal from "$lib/components/ImageModal.svelte";
|
||||||
@@ -432,9 +429,7 @@
|
|||||||
const webcalUrl = $derived(
|
const webcalUrl = $derived(
|
||||||
feedHost ? `webcal://${feedHost}/api/kalender.ics` : "#",
|
feedHost ? `webcal://${feedHost}/api/kalender.ics` : "#",
|
||||||
);
|
);
|
||||||
const icsUrl = $derived(
|
const icsUrl = $derived(feedHost ? `/api/kalender.ics` : "#");
|
||||||
feedHost ? `/api/kalender.ics` : "#",
|
|
||||||
);
|
|
||||||
const isApplePlatform = $derived(
|
const isApplePlatform = $derived(
|
||||||
feedHost
|
feedHost
|
||||||
? /iPhone|iPad|iPod|Macintosh/.test(navigator.userAgent)
|
? /iPhone|iPad|iPod|Macintosh/.test(navigator.userAgent)
|
||||||
@@ -566,7 +561,10 @@
|
|||||||
class="event-item {isNext ? 'event-item-next' : ''}"
|
class="event-item {isNext ? 'event-item-next' : ''}"
|
||||||
data-urgency={urgency}
|
data-urgency={urgency}
|
||||||
>
|
>
|
||||||
<details class="group/event" open={openByDefault || linkedSlug === eventId(item)}>
|
<details
|
||||||
|
class="group/event"
|
||||||
|
open={openByDefault || linkedSlug === eventId(item)}
|
||||||
|
>
|
||||||
<summary
|
<summary
|
||||||
class="cursor-pointer list-none p-3 flex items-start gap-3 hover:bg-himmel-50/60 focus-visible:outline focus-visible:outline-2 focus-visible:outline-himmel-500"
|
class="cursor-pointer list-none p-3 flex items-start gap-3 hover:bg-himmel-50/60 focus-visible:outline focus-visible:outline-2 focus-visible:outline-himmel-500"
|
||||||
>
|
>
|
||||||
@@ -716,12 +714,28 @@
|
|||||||
{#if item.image}
|
{#if item.image}
|
||||||
{@const imageField = extractCmsImageField(item.image)}
|
{@const imageField = extractCmsImageField(item.image)}
|
||||||
{#if imageField}
|
{#if imageField}
|
||||||
{@const thumbSrc = getCmsImageUrl(imageField.url, { width: 160, height: 160, fit: "cover" })}
|
{@const thumbSrc = getCmsImageUrl(imageField.url, {
|
||||||
{@const fullSrc = getCmsImageUrl(imageField.url, { width: 1400, fit: "contain" })}
|
width: 160,
|
||||||
{@const imageAlt = imageField.alt ?? (typeof item.image === "object" && "description" in item.image ? (item.image.description ?? "") : "")}
|
height: 160,
|
||||||
|
fit: "cover",
|
||||||
|
})}
|
||||||
|
{@const fullSrc = getCmsImageUrl(imageField.url, {
|
||||||
|
width: 1400,
|
||||||
|
fit: "contain",
|
||||||
|
})}
|
||||||
|
{@const imageAlt =
|
||||||
|
imageField.alt ??
|
||||||
|
(typeof item.image === "object" &&
|
||||||
|
"description" in item.image
|
||||||
|
? (item.image.description ?? "")
|
||||||
|
: "")}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => (modalImage = { src: fullSrc, alt: imageAlt })}
|
onclick={() =>
|
||||||
|
(modalImage = {
|
||||||
|
src: fullSrc,
|
||||||
|
alt: imageAlt,
|
||||||
|
})}
|
||||||
class="group relative w-24 h-24 rounded overflow-hidden border border-stein-200 shrink-0 hover:opacity-90 transition-opacity"
|
class="group relative w-24 h-24 rounded overflow-hidden border border-stein-200 shrink-0 hover:opacity-90 transition-opacity"
|
||||||
aria-label="Bild vergrößern"
|
aria-label="Bild vergrößern"
|
||||||
>
|
>
|
||||||
@@ -731,8 +745,14 @@
|
|||||||
class="w-full h-full object-cover"
|
class="w-full h-full object-cover"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<span class="absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/20 transition-colors">
|
<span
|
||||||
<Icon icon="mdi:magnify-plus" class="size-5 text-white opacity-0 group-hover:opacity-100 transition-opacity drop-shadow" aria-hidden="true" />
|
class="absolute inset-0 flex items-center justify-center bg-black/0 group-hover:bg-black/20 transition-colors"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
icon="mdi:magnify-plus"
|
||||||
|
class="size-5 text-white opacity-0 group-hover:opacity-100 transition-opacity drop-shadow"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -767,7 +787,9 @@
|
|||||||
class="size-3.5 shrink-0"
|
class="size-3.5 shrink-0"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<span class="whitespace-nowrap">{t(T.calendar_open_maps)}</span>
|
<span class="whitespace-nowrap"
|
||||||
|
>{t(T.calendar_open_maps)}</span
|
||||||
|
>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
{#if item.attachment?.src}
|
{#if item.attachment?.src}
|
||||||
@@ -775,10 +797,18 @@
|
|||||||
<a
|
<a
|
||||||
href={dlSrc}
|
href={dlSrc}
|
||||||
class="btn-outline btn-sm group"
|
class="btn-outline btn-sm group"
|
||||||
aria-label={item.attachment.label || "Anhang herunterladen"}
|
aria-label={item.attachment.label ||
|
||||||
|
"Anhang herunterladen"}
|
||||||
>
|
>
|
||||||
<Icon icon="mdi:file-download" class="size-3.5 shrink-0" aria-hidden="true" />
|
<Icon
|
||||||
<span class="whitespace-nowrap">{item.attachment.label || "Anhang herunterladen"}</span>
|
icon="mdi:file-download"
|
||||||
|
class="size-3.5 shrink-0"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
<span class="whitespace-nowrap"
|
||||||
|
>{item.attachment.label ||
|
||||||
|
"Anhang herunterladen"}</span
|
||||||
|
>
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
<button
|
<button
|
||||||
@@ -793,7 +823,9 @@
|
|||||||
class="size-3.5 shrink-0"
|
class="size-3.5 shrink-0"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<span class="whitespace-nowrap">{t(T.calendar_download_ics)}</span>
|
<span class="whitespace-nowrap"
|
||||||
|
>{t(T.calendar_download_ics)}</span
|
||||||
|
>
|
||||||
</button>
|
</button>
|
||||||
<a
|
<a
|
||||||
href={googleCalUrl(toICS(item))}
|
href={googleCalUrl(toICS(item))}
|
||||||
@@ -807,7 +839,9 @@
|
|||||||
class="size-3.5 shrink-0"
|
class="size-3.5 shrink-0"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<span class="whitespace-nowrap">{t(T.calendar_add_to_google)}</span>
|
<span class="whitespace-nowrap"
|
||||||
|
>{t(T.calendar_add_to_google)}</span
|
||||||
|
>
|
||||||
</a>
|
</a>
|
||||||
{#if feedHost}
|
{#if feedHost}
|
||||||
{@const shareKey =
|
{@const shareKey =
|
||||||
@@ -820,17 +854,22 @@
|
|||||||
aria-label={t(T.post_action_copy)}
|
aria-label={t(T.post_action_copy)}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
icon={copied ? "mdi:check" : "mdi:link-variant"}
|
icon={copied
|
||||||
|
? "mdi:check"
|
||||||
|
: "mdi:link-variant"}
|
||||||
class="size-3.5 shrink-0"
|
class="size-3.5 shrink-0"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<span class="whitespace-nowrap">{copied ? t(T.post_action_copied) : t(T.post_action_copy)}</span>
|
<span class="whitespace-nowrap"
|
||||||
|
>{copied
|
||||||
|
? t(T.post_action_copied)
|
||||||
|
: t(T.post_action_copy)}</span
|
||||||
|
>
|
||||||
</button>
|
</button>
|
||||||
{@const shared = shareToastKey === shareKey}
|
{@const shared = shareToastKey === shareKey}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() =>
|
onclick={() => shareEvent(item, title, locText)}
|
||||||
shareEvent(item, title, locText)}
|
|
||||||
class="btn-outline btn-sm group"
|
class="btn-outline btn-sm group"
|
||||||
aria-label={t(T.calendar_share_aria)}
|
aria-label={t(T.calendar_share_aria)}
|
||||||
>
|
>
|
||||||
@@ -841,7 +880,11 @@
|
|||||||
class="size-3.5 shrink-0"
|
class="size-3.5 shrink-0"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<span class="whitespace-nowrap">{shared ? t(T.calendar_share_copied) : t(T.calendar_share)}</span>
|
<span class="whitespace-nowrap"
|
||||||
|
>{shared
|
||||||
|
? t(T.calendar_share_copied)
|
||||||
|
: t(T.calendar_share)}</span
|
||||||
|
>
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
<button
|
<button
|
||||||
@@ -855,7 +898,9 @@
|
|||||||
class="size-3.5 shrink-0"
|
class="size-3.5 shrink-0"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
<span class="whitespace-nowrap">{t(T.calendar_jump_to_month)}</span>
|
<span class="whitespace-nowrap"
|
||||||
|
>{t(T.calendar_jump_to_month)}</span
|
||||||
|
>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -908,52 +953,52 @@
|
|||||||
Apple: webcal:// Link → öffnet nativ Kalender.app / iOS Kalender.
|
Apple: webcal:// Link → öffnet nativ Kalender.app / iOS Kalender.
|
||||||
Alle anderen: direkter ICS-Download als Fallback. -->
|
Alle anderen: direkter ICS-Download als Fallback. -->
|
||||||
{#if feedHost}
|
{#if feedHost}
|
||||||
<div
|
<div
|
||||||
class="flex flex-wrap items-center gap-2 px-4 py-2.5 border-b border-stein-200 bg-himmel-100"
|
class="flex flex-wrap items-center gap-2 px-4 py-2.5 border-b border-stein-200 bg-himmel-100"
|
||||||
>
|
>
|
||||||
{#if isApplePlatform}
|
{#if isApplePlatform}
|
||||||
<a
|
<a
|
||||||
href={webcalUrl}
|
href={webcalUrl}
|
||||||
aria-label={t(T.calendar_subscribe_aria)}
|
aria-label={t(T.calendar_subscribe_aria)}
|
||||||
class="btn-primary btn-sm inline-flex items-center gap-1.5 min-h-[36px]"
|
class="btn-primary btn-sm inline-flex items-center gap-1.5 min-h-[36px]"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
icon="mdi:calendar-plus"
|
icon="mdi:calendar-plus"
|
||||||
class="size-3.5 shrink-0"
|
class="size-3.5 shrink-0"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
{t(T.calendar_subscribe)}
|
{t(T.calendar_subscribe)}
|
||||||
</a>
|
</a>
|
||||||
{:else}
|
{:else}
|
||||||
<a
|
<a
|
||||||
href={icsUrl}
|
href={icsUrl}
|
||||||
download="windwiderstand-termine.ics"
|
download="windwiderstand-termine.ics"
|
||||||
aria-label={t(T.calendar_subscribe_aria)}
|
aria-label={t(T.calendar_subscribe_aria)}
|
||||||
class="btn-primary btn-sm inline-flex items-center gap-1.5 min-h-[36px]"
|
class="btn-primary btn-sm inline-flex items-center gap-1.5 min-h-[36px]"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
icon="mdi:calendar-plus"
|
icon="mdi:calendar-plus"
|
||||||
class="size-3.5 shrink-0"
|
class="size-3.5 shrink-0"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
{t(T.calendar_subscribe)}
|
{t(T.calendar_subscribe)}
|
||||||
</a>
|
</a>
|
||||||
{/if}
|
{/if}
|
||||||
{#if items.length > 0}
|
{#if items.length > 0}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={exportAll}
|
onclick={exportAll}
|
||||||
class="btn-outline btn-sm inline-flex items-center gap-1.5 min-h-[36px]"
|
class="btn-outline btn-sm inline-flex items-center gap-1.5 min-h-[36px]"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
icon="mdi:download"
|
icon="mdi:download"
|
||||||
class="size-3.5 shrink-0"
|
class="size-3.5 shrink-0"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
{t(T.calendar_export_all)}
|
{t(T.calendar_export_all)}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- Kalender-Widget: oben, kompakt auf Mobile-Breite gecappt (sonst
|
<!-- Kalender-Widget: oben, kompakt auf Mobile-Breite gecappt (sonst
|
||||||
@@ -964,41 +1009,45 @@
|
|||||||
class="calendar-widget bg-himmel-100 text-himmel-900 p-4"
|
class="calendar-widget bg-himmel-100 text-himmel-900 p-4"
|
||||||
>
|
>
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class="flex items-center justify-between gap-2 mb-4">
|
<div class="flex items-center justify-between gap-2 mb-2">
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
class="p-2 rounded-xs text-himmel-800 hover:bg-himmel-200 hover:text-himmel-900 transition-colors"
|
|
||||||
aria-label={t(T.calendar_prev_month)}
|
|
||||||
onclick={prevMonth}
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
icon="mdi:chevron-left"
|
|
||||||
class="size-5"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<span
|
<span
|
||||||
class="text-sm font-medium text-himmel-900 capitalize whitespace-nowrap"
|
class="text-xl font-semibold text-himmel-900 capitalize whitespace-nowrap"
|
||||||
>{monthLabel}</span
|
>{monthLabel}</span
|
||||||
>
|
>
|
||||||
<button
|
<div class="flex items-center gap-0.5">
|
||||||
type="button"
|
<button
|
||||||
class="p-2 rounded-xs text-himmel-800 hover:bg-himmel-200 hover:text-himmel-900 transition-colors"
|
type="button"
|
||||||
aria-label={t(T.calendar_next_month)}
|
class="p-2 rounded-xs text-himmel-800 hover:bg-himmel-200 hover:text-himmel-900 transition-colors"
|
||||||
onclick={nextMonth}
|
aria-label={t(T.calendar_prev_month)}
|
||||||
>
|
onclick={prevMonth}
|
||||||
<Icon
|
>
|
||||||
icon="mdi:chevron-right"
|
<Icon
|
||||||
class="size-5"
|
icon="mdi:chevron-left"
|
||||||
aria-hidden="true"
|
class="size-5"
|
||||||
/>
|
aria-hidden="true"
|
||||||
</button>
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="p-2 rounded-xs text-himmel-800 hover:bg-himmel-200 hover:text-himmel-900 transition-colors"
|
||||||
|
aria-label={t(T.calendar_next_month)}
|
||||||
|
onclick={nextMonth}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
icon="mdi:chevron-right"
|
||||||
|
class="size-5"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<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}
|
{#each weekdays as w, i}
|
||||||
<div
|
<div
|
||||||
class="py-1.5 text-xs font-semibold text-himmel-800"
|
class="py-1.5 text-xs font-bold rounded-xs {i >= 5
|
||||||
|
? 'bg-stein-100/80 text-stein-600'
|
||||||
|
: 'bg-himmel-200/50 text-himmel-800'}"
|
||||||
>
|
>
|
||||||
{w}
|
{w}
|
||||||
</div>
|
</div>
|
||||||
@@ -1014,14 +1063,22 @@
|
|||||||
{@const isSelected = selectedDay === key}
|
{@const isSelected = selectedDay === key}
|
||||||
{@const isToday = key === todayKey}
|
{@const isToday = key === todayKey}
|
||||||
{@const isFuture = key >= todayKey}
|
{@const isFuture = key >= todayKey}
|
||||||
|
{@const isWeekend =
|
||||||
|
d.getDay() === 0 || d.getDay() === 6}
|
||||||
{#if hasEvents}
|
{#if hasEvents}
|
||||||
<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 {isCurrentMonth
|
class="relative h-10 rounded-xs flex flex-col items-center justify-center min-w-0 transition-colors cursor-pointer font-semibold
|
||||||
? 'text-himmel-900 hover:bg-himmel-200'
|
{isCurrentMonth
|
||||||
: 'text-himmel-700 opacity-60 hover:opacity-80'} bg-himmel-200/70 font-semibold hover:bg-himmel-300 {isSelected
|
? 'text-himmel-900'
|
||||||
? 'ring-2 ring-himmel-700 bg-himmel-300'
|
: 'text-himmel-700 opacity-60 hover:opacity-80'}
|
||||||
: ''} {isToday ? 'today-cell' : ''}"
|
{isWeekend
|
||||||
|
? 'bg-erde-100 hover:bg-erde-200'
|
||||||
|
: 'bg-himmel-200/80 hover:bg-himmel-300'}
|
||||||
|
{isSelected
|
||||||
|
? 'ring-2 ring-himmel-700 brightness-95'
|
||||||
|
: ''}
|
||||||
|
{isToday ? 'today-cell' : ''}"
|
||||||
onclick={() => selectDay(key)}
|
onclick={() => selectDay(key)}
|
||||||
onmouseenter={(e) => showTooltip(e, key)}
|
onmouseenter={(e) => showTooltip(e, key)}
|
||||||
onmouseleave={hideTooltip}
|
onmouseleave={hideTooltip}
|
||||||
@@ -1049,11 +1106,14 @@
|
|||||||
</button>
|
</button>
|
||||||
{:else}
|
{:else}
|
||||||
<div
|
<div
|
||||||
class="relative h-10 rounded-xs flex flex-col items-center justify-center min-w-0 cursor-default bg-himmel-50/40 {isCurrentMonth
|
class="relative h-10 rounded-xs flex flex-col items-center justify-center min-w-0 cursor-default
|
||||||
|
{isWeekend
|
||||||
|
? 'bg-stein-100/60'
|
||||||
|
: 'bg-himmel-50/50'}
|
||||||
|
{isCurrentMonth
|
||||||
? 'text-himmel-800'
|
? 'text-himmel-800'
|
||||||
: 'text-himmel-600 opacity-50'} {isToday
|
: 'text-himmel-600 opacity-50'}
|
||||||
? 'today-cell'
|
{isToday ? 'today-cell' : ''}"
|
||||||
: ''}"
|
|
||||||
aria-current={isToday ? "date" : undefined}
|
aria-current={isToday ? "date" : undefined}
|
||||||
>
|
>
|
||||||
<span class="text-xs">{d.getDate()}</span>
|
<span class="text-xs">{d.getDate()}</span>
|
||||||
@@ -1080,19 +1140,23 @@
|
|||||||
>
|
>
|
||||||
{#each tooltipEvents.slice(0, 3) as ev}
|
{#each tooltipEvents.slice(0, 3) as ev}
|
||||||
<div class="cal-tooltip-row">
|
<div class="cal-tooltip-row">
|
||||||
<span class="cal-tooltip-title">{ev.title || t(T.calendar_untitled)}</span>
|
<span class="cal-tooltip-title"
|
||||||
|
>{ev.title || t(T.calendar_untitled)}</span
|
||||||
|
>
|
||||||
{#if ev.timeStr}
|
{#if ev.timeStr}
|
||||||
<span class="cal-tooltip-time">{ev.timeStr}</span>
|
<span class="cal-tooltip-time">{ev.timeStr}</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
{#if tooltipEvents.length > 3}
|
{#if tooltipEvents.length > 3}
|
||||||
<div class="cal-tooltip-more">+{tooltipEvents.length - 3} weitere</div>
|
<div class="cal-tooltip-more">
|
||||||
|
+{tooltipEvents.length - 3} weitere
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- Events: voll Breite, unten. Akkordeon-Liste, in natürlichem
|
<!-- Events: voll Breite, unten. Akkordeon-Liste, in natürlichem
|
||||||
Page-Flow (kein internes Scrollen). Kalender-Klick filtert auf
|
Page-Flow (kein internes Scrollen). Kalender-Klick filtert auf
|
||||||
einen Tag; ohne Filter Liste ab heute, gruppiert nach Tag. -->
|
einen Tag; ohne Filter Liste ab heute, gruppiert nach Tag. -->
|
||||||
<div class="calendar-events-panel bg-stein-0 border-t border-stein-200">
|
<div class="calendar-events-panel bg-stein-0 border-t border-stein-200">
|
||||||
@@ -1225,7 +1289,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if modalImage}
|
{#if modalImage}
|
||||||
<ImageModal src={modalImage.src} alt={modalImage.alt} onclose={() => (modalImage = null)} />
|
<ImageModal
|
||||||
|
src={modalImage.src}
|
||||||
|
alt={modalImage.alt}
|
||||||
|
onclose={() => (modalImage = null)}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -1235,7 +1303,11 @@
|
|||||||
.calendar-block .today-cell {
|
.calendar-block .today-cell {
|
||||||
outline: 2px solid var(--color-wald-400, #84e0a4);
|
outline: 2px solid var(--color-wald-400, #84e0a4);
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
background-color: color-mix(in srgb, var(--color-wald-200, #bbf0cf) 40%, transparent);
|
background-color: color-mix(
|
||||||
|
in srgb,
|
||||||
|
var(--color-wald-200, #bbf0cf) 40%,
|
||||||
|
transparent
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/* Event-Rows visuell trennen: Card-Optik mit Urgency-Akzent links,
|
/* Event-Rows visuell trennen: Card-Optik mit Urgency-Akzent links,
|
||||||
Zebra-Stripe ab dem zweiten Eintrag, deutlicher Separator
|
Zebra-Stripe ab dem zweiten Eintrag, deutlicher Separator
|
||||||
|
|||||||
Reference in New Issue
Block a user