style(design): consistency sweep + UX upgrades
Deploy / verify (push) Successful in 49s
Deploy / deploy (push) Successful in 1m0s

- 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>
This commit is contained in:
Peter Meier
2026-05-05 01:06:22 +02:00
parent 3ded972642
commit b7093b703a
42 changed files with 280 additions and 234 deletions
+55 -6
View File
@@ -315,13 +315,65 @@ main ol:not(.not-prose) li {
/* Buttons Wald (Primary) */
.btn-primary {
@apply inline-block no-underline transition-colors duration-200 font-light px-4 py-2 rounded-md shadow-sm bg-btn-bg text-btn-txt;
@apply inline-block no-underline transition-colors duration-200 font-medium px-4 py-2 rounded-xs shadow-sm bg-btn-bg text-btn-txt;
}
.btn-primary:hover {
@apply bg-btn-hover-bg;
}
/* Buttons Stein outline (Secondary) */
.btn-secondary {
@apply inline-block no-underline transition-colors duration-200 font-medium px-4 py-2 rounded-xs border border-stein-300 bg-white text-stein-700 shadow-sm;
}
.btn-secondary:hover {
@apply bg-stein-100 border-stein-400;
}
/* Globaler Focus-Ring wald-Akzent für Tastatur-Nutzer (a11y + Polish) */
*:focus-visible {
outline: 2px solid var(--color-wald-500);
outline-offset: 2px;
border-radius: 2px;
}
/* Lead-Paragraph: erstes <p> in einem Top-Level MarkdownBlock größer + leichter
(Editorial). Bewusst nur via [data-block-type="markdown"] gescopt — sonst
würden auch Card-Beschreibungen mit `.markdown` getroffen. */
[data-block-type="markdown"] .markdown > p:first-child {
font-size: 1.25rem;
line-height: 1.55;
font-weight: 300;
color: var(--text-secondary);
margin-bottom: 1.25em;
}
@media (min-width: 768px) {
[data-block-type="markdown"] .markdown > p:first-child {
font-size: 1.375rem;
}
}
/* Content-Row-Trenner: subtiler wald-Verlauf zwischen content-rows (Forest-Identität) */
.content-row + .content-row {
position: relative;
margin-top: 2rem;
}
.content-row + .content-row::before {
content: "";
display: block;
height: 1px;
background: linear-gradient(
90deg,
transparent,
var(--color-wald-200),
transparent
);
margin: 0 auto 2rem;
max-width: 50%;
}
/* Content-Blöcke */
.content p {
@apply mb-4;
@@ -372,7 +424,7 @@ main ol:not(.not-prose) li {
/* Markdown-Bilder: /cms-images-Transform, max-height begrenzt Höhe; Link öffnet Bild in neuem Tab */
.markdown img {
@apply max-w-full w-full my-2 border border-stein-200 rounded-md bg-stein-200 shadow-sm inline-block;
@apply max-w-full w-full my-2 border border-stein-200 rounded-xs bg-stein-200 shadow-sm inline-block;
max-height: 30vh;
}
@@ -423,7 +475,7 @@ main code,
main pre,
.content pre,
.markdown pre {
@apply mt-3 mb-4 overflow-x-auto rounded-md border border-stein-200 bg-stein-100 px-4 py-3 text-stein-800 leading-normal;
@apply mt-3 mb-4 overflow-x-auto rounded-xs border border-stein-200 bg-stein-100 px-4 py-3 text-stein-800 leading-normal;
}
main pre code,
@@ -462,9 +514,6 @@ blockquote[data-block-type="quote"] cite {
font-family: var(--font-secondary);
}
.content-row + .content-row {
margin-top: 1.5rem;
}
/* Footer */
footer a,
+1 -1
View File
@@ -32,7 +32,7 @@
}
</script>
<details {id} {open} ontoggle={onToggle} class="pt-4 border-t border-zinc-200 group {cls}">
<details {id} {open} ontoggle={onToggle} class="pt-4 border-t border-stein-200 group {cls}">
<summary class="flex cursor-pointer list-none items-center gap-2 text-sm font-medium select-none">
<Icon icon="mdi:chevron-right" class="size-4 shrink-0 transition-transform group-open:rotate-90" />
{label}
+1 -1
View File
@@ -11,7 +11,7 @@
switch (c) {
case "green": return "bg-wald-50 text-wald-700 border border-wald-200";
case "blue": return "bg-himmel-50 text-himmel-700 border border-himmel-200";
case "amber": return "bg-[#fdf8ec] text-[#a6780a] border border-[#f0d98a]";
case "amber": return "bg-erde-50 text-erde-700 border border-erde-200";
default: return "bg-stein-100 text-stein-600 border border-stein-200";
}
}
+17 -17
View File
@@ -133,7 +133,7 @@
<label class="relative block w-full sm:max-w-sm">
<span class="sr-only">{t(T.blog_search_label)}</span>
<span
class="pointer-events-none absolute top-1/2 left-2 -translate-y-1/2 text-zinc-500"
class="pointer-events-none absolute top-1/2 left-2 -translate-y-1/2 text-stein-500"
>
<Icon icon="mdi:magnify" class="h-4 w-4" />
</span>
@@ -141,13 +141,13 @@
type="search"
bind:value={query}
placeholder={t(T.blog_search_placeholder)}
class="w-full rounded-sm border border-zinc-300 bg-white py-2 pr-9 pl-8 text-sm focus:border-zinc-500 focus:outline-none"
class="w-full rounded-xs border border-stein-300 bg-white py-2 pr-9 pl-8 text-sm focus:border-stein-500 focus:outline-none"
/>
{#if query}
<button
type="button"
onclick={() => (query = "")}
class="absolute top-1/2 right-1.5 -translate-y-1/2 rounded-sm p-1 text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900"
class="absolute top-1/2 right-1.5 -translate-y-1/2 rounded-xs p-1 text-stein-500 hover:bg-stein-100 hover:text-stein-900"
aria-label={t(T.blog_search_clear)}
>
<Icon icon="mdi:close" class="h-4 w-4" />
@@ -158,13 +158,13 @@
<label class="relative inline-flex items-center">
<span class="sr-only">{t(T.blog_year_label)}</span>
<span
class="pointer-events-none absolute top-1/2 left-2 -translate-y-1/2 text-zinc-500"
class="pointer-events-none absolute top-1/2 left-2 -translate-y-1/2 text-stein-500"
>
<Icon icon="mdi:calendar" class="h-4 w-4" />
</span>
<select
bind:value={year}
class="appearance-none rounded-sm border border-zinc-300 bg-white py-2 pr-7 pl-8 text-sm focus:border-zinc-500 focus:outline-none"
class="appearance-none rounded-xs border border-stein-300 bg-white py-2 pr-7 pl-8 text-sm focus:border-stein-500 focus:outline-none"
>
<option value="">{t(T.blog_year_all)}</option>
{#each availableYears as y}
@@ -172,7 +172,7 @@
{/each}
</select>
<span
class="pointer-events-none absolute top-1/2 right-1.5 -translate-y-1/2 text-zinc-500"
class="pointer-events-none absolute top-1/2 right-1.5 -translate-y-1/2 text-stein-500"
>
<Icon icon="mdi:chevron-down" class="h-4 w-4" />
</span>
@@ -183,10 +183,10 @@
{#if !isFiltering && upcomingEvents.length > 0}
<section
class="not-prose mb-6 rounded-sm border border-zinc-200 bg-zinc-50 p-4"
class="not-prose mb-6 rounded-xs border border-stein-200 bg-stein-50 p-4"
>
<h2
class="mb-3 flex items-center gap-2 text-sm font-semibold tracking-wide text-zinc-700"
class="mb-3 flex items-center gap-2 text-sm font-semibold tracking-wide text-stein-700"
>
<Icon icon="mdi:calendar-clock" class="size-7 shrink-0" />
{t(T.blog_upcoming_events)}
@@ -200,7 +200,7 @@
>
<EventBadges eventDate={ev.eventDate} />
<span
class="text-sm text-zinc-900 group-hover:text-zinc-950"
class="text-sm text-stein-900 group-hover:text-stein-900"
>{ev.headline}</span
>
</a>
@@ -212,7 +212,7 @@
{#if isFiltering}
<div
class="mb-3 flex flex-wrap items-center gap-2 text-xs text-zinc-600"
class="mb-3 flex flex-wrap items-center gap-2 text-xs text-stein-600"
>
<span>
{t(T.blog_results_count, { count: filteredResults.length })}
@@ -225,7 +225,7 @@
query = "";
year = "";
}}
class="text-zinc-500 underline hover:text-zinc-900"
class="text-stein-500 underline hover:text-stein-900"
>{t(T.blog_filter_reset)}</button
>
</div>
@@ -236,11 +236,11 @@
{#each filteredResults as hit}
<a
href={searchResultHref(hit.slug)}
class="flex flex-col overflow-hidden border border-gray-200 bg-white text-slate-950 no-underline transition-all"
class="flex flex-col overflow-hidden border border-stein-200 bg-white text-stein-900 no-underline transition-colors"
>
{#if hit.image}
<div
class="aspect-3/2 w-full overflow-hidden bg-gray-100"
class="aspect-3/2 w-full overflow-hidden bg-stein-100"
>
<img
src={hit.image}
@@ -255,7 +255,7 @@
{hit.headline}
</h3>
{#if hit.excerpt}
<p class="text-sm text-zinc-700 line-clamp-3">
<p class="text-sm text-stein-700 line-clamp-3">
{hit.excerpt}
</p>
{/if}
@@ -265,7 +265,7 @@
</div>
{:else}
<div
class="rounded-sm border border-zinc-200 bg-white p-6 text-center text-sm text-zinc-600"
class="rounded-xs border border-stein-200 bg-white p-6 text-center text-sm text-stein-600"
>
{t(T.blog_no_results)}
</div>
@@ -318,7 +318,7 @@
<div class="flex flex-wrap items-center gap-2">
<Pagination {currentPage} {totalPages} {basePath} {activeTag} />
<div class="grow"></div>
<div class="bg-white rounded-md font-thin">
<div class="bg-white rounded-xs font-light">
<div class="inline-flex text-xs p-2">
{#if totalCount > 0}
{t(T.blog_count, {
@@ -339,7 +339,7 @@
</div>
</div>
<div class="mt-4 text-xs text-zinc-600">
<div class="mt-4 text-xs text-stein-600">
<a
href="/posts/rss.xml"
class="inline-flex items-center gap-1 hover:underline"
+5 -5
View File
@@ -25,19 +25,19 @@
variant: "tile",
layout: "stack",
class:
"flex flex-col gap-2 border border-gray-200 bg-white p-4 text-slate-950",
"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-gray-200 bg-white p-4 text-slate-950",
"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-gray-200 bg-white p-0 text-slate-950",
"flex flex-col gap-0 border border-stein-200 bg-white p-0 text-stein-900",
},
],
defaultVariants: { variant: "tile", layout: "stack" },
@@ -46,8 +46,8 @@
const cardAsLink = cva("", {
variants: {
variant: {
callout: "cursor-pointer transition-all no-underline text-inherit",
tile: "transition-all no-underline hover:border-gray-300",
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" },
+40 -40
View File
@@ -305,32 +305,32 @@
bind:value={editBody}
use:autosize
onkeydown={submitOnCmdEnter}
class="w-full p-2 border border-zinc-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-zinc-400"
class="w-full p-2 border border-stein-300 rounded-xs text-sm focus:outline-none focus:ring-2 focus:ring-stein-400"
rows="2"
maxlength={bodyMax}
></textarea>
<div class="mt-1 flex items-center gap-3 text-xs">
<button
type="submit"
class="rounded bg-zinc-800 px-3 py-1 font-medium text-white hover:bg-zinc-700"
class="rounded-xs bg-stein-800 px-3 py-1 font-medium text-white hover:bg-stein-700"
>{t(T.comments_save)}</button>
<button
type="button"
onclick={cancelEdit}
class="text-zinc-500 hover:text-zinc-900"
class="text-stein-500 hover:text-stein-900"
>{t(T.comments_cancel)}</button>
<span class="ml-auto text-zinc-400 tabular-nums">{editBody.length} / {bodyMax}</span>
<span class="ml-auto text-stein-400 tabular-nums">{editBody.length} / {bodyMax}</span>
</div>
{#if editError}<p class="text-red-700 text-xs mt-1">{editError}</p>{/if}
{#if editError}<p class="text-fire-700 text-xs mt-1">{editError}</p>{/if}
</form>
{:else}
<p class="mt-1 whitespace-pre-wrap text-sm leading-relaxed text-zinc-800">{c.body}</p>
<p class="mt-1 whitespace-pre-wrap text-sm leading-relaxed text-stein-800">{c.body}</p>
{#if c.can_edit}
<div class="mt-1 flex gap-3 opacity-60 group-hover:opacity-100 transition-opacity">
<button
type="button"
onclick={() => startEdit(c)}
class="text-xs text-zinc-600 hover:text-zinc-900 inline-flex items-center gap-1"
class="text-xs text-stein-600 hover:text-stein-900 inline-flex items-center gap-1"
>
<Icon icon="mdi:pencil-outline" class="size-3" />
{t(T.comments_edit)}
@@ -338,7 +338,7 @@
<button
type="button"
onclick={() => deleteComment(c.id)}
class="text-xs text-zinc-600 hover:text-red-700 inline-flex items-center gap-1"
class="text-xs text-stein-600 hover:text-fire-700 inline-flex items-center gap-1"
>
<Icon icon="mdi:trash-can-outline" class="size-3" />
{t(T.comments_delete)}
@@ -350,20 +350,20 @@
{#snippet meta(c: PublicComment)}
<div class="flex flex-wrap items-baseline gap-2 text-sm">
<strong class="font-medium text-zinc-900">{c.author}</strong>
<strong class="font-medium text-stein-900">{c.author}</strong>
{#if c.can_edit}
<span class="text-[10px] uppercase tracking-wide text-zinc-400">{t(T.comments_self_marker)}</span>
<span class="text-[10px] uppercase tracking-wide text-stein-400">{t(T.comments_self_marker)}</span>
{/if}
<time
class="text-zinc-500 text-xs"
class="text-stein-500 text-xs"
datetime={c.created_at}
title={fmtAbs(c.created_at)}
>{fmtRel(c.created_at)}</time>
{#if c.updated_at}
<span class="text-zinc-400 text-xs" title={fmtAbs(c.updated_at)}>{t(T.comments_edited)}</span>
<span class="text-stein-400 text-xs" title={fmtAbs(c.updated_at)}>{t(T.comments_edited)}</span>
{/if}
{#if c.status === "pending"}
<span class="ml-auto inline-flex items-center gap-1 rounded-full bg-amber-100 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-amber-800">
<span class="ml-auto inline-flex items-center gap-1 rounded-full bg-erde-100 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-erde-800">
<Icon icon="mdi:clock-outline" class="size-3" />
{t(T.comments_pending_short)}
</span>
@@ -376,33 +376,33 @@
<ul class="space-y-4 list-none p-0" aria-busy="true" aria-label={t(T.comments_loading)}>
{#each Array(2) as _, i (i)}
<li class="flex gap-3 list-none!">
<div class="size-9 shrink-0 rounded-full bg-zinc-200 animate-pulse"></div>
<div class="size-9 shrink-0 rounded-full bg-stein-200 animate-pulse"></div>
<div class="flex-1 space-y-2">
<div class="h-3 w-32 bg-zinc-200 rounded animate-pulse"></div>
<div class="h-3 w-full bg-zinc-200 rounded animate-pulse"></div>
<div class="h-3 w-3/4 bg-zinc-200 rounded animate-pulse"></div>
<div class="h-3 w-32 bg-stein-200 rounded-xs animate-pulse"></div>
<div class="h-3 w-full bg-stein-200 rounded-xs animate-pulse"></div>
<div class="h-3 w-3/4 bg-stein-200 rounded-xs animate-pulse"></div>
</div>
</li>
{/each}
</ul>
{:else if loadError}
<div class="flex items-start gap-2 rounded border border-red-200 bg-red-50 p-3 text-sm text-red-800">
<div class="flex items-start gap-2 rounded-xs border border-fire-200 bg-fire-50 p-3 text-sm text-fire-800">
<Icon icon="mdi:alert-circle-outline" class="size-5 shrink-0 mt-0.5" />
<div class="flex-1">
<p class="font-medium">{t(T.comments_load_error_title)}</p>
<p class="mt-1 text-xs text-red-700">{loadError}</p>
<p class="mt-1 text-xs text-fire-700">{loadError}</p>
</div>
<button
type="button"
onclick={loadComments}
class="text-xs text-red-800 underline hover:no-underline"
class="text-xs text-fire-800 underline hover:no-underline"
>{t(T.comments_retry)}</button>
</div>
{:else}
{#if topLevel.length === 0}
<div class="flex flex-col items-center gap-2 py-8 text-center sm:flex-row sm:items-center sm:text-left sm:py-4 sm:gap-3">
<Icon icon="mdi:comment-text-outline" class="size-10 text-zinc-300 shrink-0" />
<p class="text-sm text-zinc-500">{t(T.comments_empty)}</p>
<Icon icon="mdi:comment-text-outline" class="size-10 text-stein-300 shrink-0" />
<p class="text-sm text-stein-500">{t(T.comments_empty)}</p>
</div>
{:else}
<ul class="space-y-5 mb-8 list-none p-0">
@@ -410,7 +410,7 @@
{@const replies = repliesOf(c.id)}
<li
class="group flex gap-3 list-none! {c.status === 'pending'
? 'rounded-md border border-amber-200 bg-amber-50/50 p-3'
? 'rounded-xs border border-erde-200 bg-erde-50/50 p-3'
: ''}"
>
{@render avatar(c.author)}
@@ -422,7 +422,7 @@
<button
type="button"
onclick={() => (replyTo = replyTo === c.id ? null : c.id)}
class="text-xs text-zinc-600 hover:text-zinc-900 inline-flex items-center gap-1"
class="text-xs text-stein-600 hover:text-stein-900 inline-flex items-center gap-1"
>
<Icon icon="mdi:reply" class="size-3" />
{replyTo === c.id
@@ -443,7 +443,7 @@
placeholder={t(T.comments_name_placeholder)}
required
maxlength="80"
class="w-full p-2 border border-zinc-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-zinc-400"
class="w-full p-2 border border-stein-300 rounded-xs text-sm focus:outline-none focus:ring-2 focus:ring-stein-400"
/>
<textarea
bind:value={replyBody}
@@ -453,26 +453,26 @@
required
rows="2"
maxlength={bodyMax}
class="w-full p-2 border border-zinc-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-zinc-400"
class="w-full p-2 border border-stein-300 rounded-xs text-sm focus:outline-none focus:ring-2 focus:ring-stein-400"
></textarea>
{#if replyError}<p class="text-red-700 text-xs">{replyError}</p>{/if}
{#if replyError}<p class="text-fire-700 text-xs">{replyError}</p>{/if}
<div class="flex items-center gap-2">
<button
type="submit"
disabled={submitting}
class="px-3 py-1.5 bg-zinc-800 text-white rounded text-sm font-medium hover:bg-zinc-700 disabled:opacity-50"
class="px-3 py-1.5 bg-stein-800 text-white rounded-xs text-sm font-medium hover:bg-stein-700 disabled:opacity-50"
>{t(T.comments_reply_send)}</button>
<span class="ml-auto text-xs text-zinc-400 tabular-nums">{replyBody.length} / {bodyMax}</span>
<span class="ml-auto text-xs text-stein-400 tabular-nums">{replyBody.length} / {bodyMax}</span>
</div>
</form>
{/if}
{#if replies.length > 0}
<ul class="mt-4 space-y-4 list-none p-0 border-l border-zinc-200 pl-4">
<ul class="mt-4 space-y-4 list-none p-0 border-l border-stein-200 pl-4">
{#each replies as r (r.id)}
<li
class="group flex gap-3 list-none! {r.status === 'pending'
? 'rounded-md border border-amber-200 bg-amber-50/50 p-2'
? 'rounded-xs border border-erde-200 bg-erde-50/50 p-2'
: ''}"
>
{@render avatar(r.author, "sm")}
@@ -490,15 +490,15 @@
</ul>
{/if}
<form onsubmit={onSubmit} class="border-t border-zinc-200 pt-5 space-y-3">
<h3 class="font-medium text-sm text-zinc-900">{t(T.comments_form_title)}</h3>
<form onsubmit={onSubmit} class="border-t border-stein-200 pt-5 space-y-3">
<h3 class="font-medium text-sm text-stein-900">{t(T.comments_form_title)}</h3>
<input
type="text"
bind:value={author}
placeholder={t(T.comments_name_placeholder)}
required
maxlength="80"
class="w-full p-2 border border-zinc-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-zinc-400"
class="w-full p-2 border border-stein-300 rounded-xs text-sm focus:outline-none focus:ring-2 focus:ring-stein-400"
/>
<textarea
bind:value={body}
@@ -508,7 +508,7 @@
required
rows="3"
maxlength={bodyMax}
class="w-full p-2 border border-zinc-300 rounded text-sm focus:outline-none focus:ring-2 focus:ring-zinc-400"
class="w-full p-2 border border-stein-300 rounded-xs text-sm focus:outline-none focus:ring-2 focus:ring-stein-400"
></textarea>
<input
type="text"
@@ -519,26 +519,26 @@
class="absolute left-[-9999px]"
/>
{#if submitError}
<p class="text-red-700 text-xs">{submitError}</p>
<p class="text-fire-700 text-xs">{submitError}</p>
{/if}
<div class="flex flex-wrap items-center gap-3 text-xs">
<button
type="submit"
disabled={submitting || !body.trim() || !author.trim()}
class="px-4 py-2 bg-zinc-800 text-white rounded text-sm font-medium hover:bg-zinc-700 disabled:opacity-50 disabled:cursor-not-allowed"
class="px-4 py-2 bg-stein-800 text-white rounded-xs text-sm font-medium hover:bg-stein-700 disabled:opacity-50 disabled:cursor-not-allowed"
>
{submitting ? t(T.comments_sending) : t(T.comments_send)}
</button>
{#if requireApproval}
<span class="text-zinc-500 inline-flex items-center gap-1">
<span class="text-stein-500 inline-flex items-center gap-1">
<Icon icon="mdi:shield-check-outline" class="size-3.5" />
{t(T.comments_approval_hint)}
</span>
{/if}
<span class="ml-auto text-zinc-400 tabular-nums">{body.length} / {bodyMax}</span>
<span class="ml-auto text-stein-400 tabular-nums">{body.length} / {bodyMax}</span>
</div>
{#if totalPending > 0}
<p class="text-xs text-zinc-500 italic">
<p class="text-xs text-stein-500 italic">
{totalPending === 1
? t(T.comments_pending_summary_one)
: t(T.comments_pending_summary_other, { count: totalPending })}
+1 -1
View File
@@ -145,7 +145,7 @@
{:else if blockType(item) === "live_strommix"}
<StrommixBlock block={item as LiveStrommixBlockData} />
{:else}
<div class="col-span-12 rounded border border-amber-200 bg-amber-50 px-3 py-2 text-sm text-amber-800">
<div class="col-span-12 rounded border border-erde-200 bg-erde-50 px-3 py-2 text-sm text-erde-800">
Unbekannter Block: <code>{blockType(item)}</code>
</div>
{/if}
+2 -2
View File
@@ -34,12 +34,12 @@
{/if}
{#if locationText}
{#if locationHref}
<a href={locationHref} target={locationHref.startsWith('#') ? undefined : '_blank'} rel={locationHref.startsWith('#') ? undefined : 'noopener noreferrer'} class="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-neutral-800 text-neutral-50! px-3 py-1 text-[.65rem] shadow-sm hover:bg-neutral-700 transition-colors no-underline!">
<a href={locationHref} target={locationHref.startsWith('#') ? undefined : '_blank'} rel={locationHref.startsWith('#') ? undefined : 'noopener noreferrer'} class="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-stein-800 text-stein-50! px-3 py-1 text-[.65rem] shadow-sm hover:bg-stein-700 transition-colors no-underline!">
<Icon icon="mdi:map-marker" class="size-3.5 shrink-0 opacity-90" aria-hidden="true" />
{locationText}
</a>
{:else}
<span class="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-neutral-800 text-neutral-50 px-3 py-1 text-[.65rem] font-medium shadow-sm no-underline! [text-decoration:none]">
<span class="inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full bg-stein-800 text-stein-50 px-3 py-1 text-[.65rem] font-medium shadow-sm no-underline! [text-decoration:none]">
<Icon icon="mdi:map-marker" class="size-3.5 shrink-0 opacity-90" aria-hidden="true" />
{locationText}
</span>
+1 -1
View File
@@ -44,7 +44,7 @@
onclick={() => { overlayVisible = false; }}
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') overlayVisible = false; }}
>
<div class="flex items-center gap-2 rounded-full bg-white/90 px-4 py-2 text-xs font-medium text-zinc-700 shadow">
<div class="flex items-center gap-2 rounded-full bg-white/90 px-4 py-2 text-xs font-medium text-stein-700 shadow">
<Icon icon="mdi:cursor-default-click" class="size-4 shrink-0" aria-hidden="true" />
{t(translations, T.post_map_activate)}
</div>
+8 -8
View File
@@ -24,16 +24,16 @@
{#if footer}
<footer
class="mt-auto bg-zinc-950 text-white py-10"
class="mt-auto bg-stein-900 text-stein-0 py-10"
data-footer-id={footer.id}
>
<div class="container-custom">
{#if hasRowContent}
<div class="content-footer text-sm text-zinc-200">
<div class="content-footer text-sm text-stein-200">
<ContentRows layout={footer} translations={translations} />
</div>
{:else}
<p class="text-sm text-white/80 text-center">
<p class="text-sm text-stein-0/80 text-center">
{t(T.footer_copyright) !== T.footer_copyright
? t(T.footer_copyright)
: `© ${new Date().getFullYear()} Windwiderstand`}
@@ -61,19 +61,19 @@
.content-footer :global(.content-row + .content-row) {
margin-top: 2rem;
padding-top: 1.5rem;
border-top: 1px solid rgb(63 63 70);
border-top: 1px solid var(--color-stein-700);
}
.content-footer :global(a) {
color: rgb(228 228 231);
color: var(--color-stein-200);
}
.content-footer :global(a:hover) {
color: rgb(255 255 255);
color: var(--color-stein-0);
}
.content-footer :global(h3) {
color: rgb(250 250 250);
color: var(--color-stein-0);
}
.content-footer :global(.markdown),
.content-footer :global(.prose) {
color: rgb(212 212 216);
color: var(--color-stein-200);
}
</style>
+15 -32
View File
@@ -126,20 +126,13 @@
aria-label={t(T.header_nav_aria)}
>
{#each links as link}
{@const active = isActiveLink(link.href, $page.url.pathname)}
<a
href={link.href}
class="hover:animate-pulse transition-all text-[.7rem]"
class:font-bold={isActiveLink(
link.href,
$page.url.pathname,
)}
class:underline={isActiveLink(
link.href,
$page.url.pathname,
)}
aria-current={isActiveLink(link.href, $page.url.pathname)
? "page"
: undefined}
class="text-[.7rem] py-1 transition-colors hover:text-wald-700 {active
? 'font-bold text-wald-700 border-b-2 border-wald-600'
: 'border-b-2 border-transparent'}"
aria-current={active ? "page" : undefined}
>
{link.label}
</a>
@@ -150,7 +143,7 @@
href={social.href}
target="_blank"
rel="noopener noreferrer"
class="p-1.5 -m-1.5 rounded-md transition-colors flex items-center justify-center"
class="p-1.5 -m-1.5 rounded-xs transition-colors flex items-center justify-center"
aria-label={social.label || t(T.header_social_aria)}
>
<Icon icon={social.icon} aria-hidden="true" />
@@ -158,7 +151,7 @@
{/each}
<button
type="button"
class="p-2 -mr-2 rounded-md transition-colors flex items-center justify-center"
class="p-2 -mr-2 rounded-xs transition-colors flex items-center justify-center"
aria-label={searchOpen
? t(T.header_search_close)
: t(T.header_search_open)}
@@ -182,7 +175,7 @@
<div class="lg:hidden flex items-center gap-1">
<button
type="button"
class="p-2 rounded-md transition-colors flex items-center justify-center"
class="p-2 rounded-xs transition-colors flex items-center justify-center"
aria-label={searchOpen
? t(T.header_search_close)
: t(T.header_search_open)}
@@ -206,7 +199,7 @@
</button>
<button
type="button"
class="p-2 -mr-2 hover:bg-stein-0/10 rounded-md transition-colors flex items-center justify-center"
class="p-2 -mr-2 hover:bg-stein-0/10 rounded-xs transition-colors flex items-center justify-center"
aria-label={menuOpen
? t(T.header_menu_close)
: t(T.header_menu_open)}
@@ -249,23 +242,13 @@
aria-label={t(T.header_nav_aria)}
>
{#each links as link}
{@const active = isActiveLink(link.href, $page.url.pathname)}
<a
href={link.href}
class="block py-3 px-2 text-stein-100 hover:text-stein-0 hover:bg-stein-0/10 rounded-md transition-colors text-sm"
class:font-bold={isActiveLink(
link.href,
$page.url.pathname,
)}
class:underline={isActiveLink(
link.href,
$page.url.pathname,
)}
aria-current={isActiveLink(
link.href,
$page.url.pathname,
)
? "page"
: undefined}
class="block py-4 px-3 rounded-xs transition-colors text-base {active
? 'font-bold text-wald-300 bg-wald-700/20 border-l-4 border-wald-400'
: 'text-stein-100 hover:text-stein-0 hover:bg-stein-0/10 border-l-4 border-transparent'}"
aria-current={active ? 'page' : undefined}
onclick={closeMenu}
>
{link.label}
@@ -280,7 +263,7 @@
href={social.href}
target="_blank"
rel="noopener noreferrer"
class="inline-flex p-2 text-stein-100 hover:text-stein-0 hover:bg-stein-0/10 rounded-md transition-colors"
class="inline-flex p-2 text-stein-100 hover:text-stein-0 hover:bg-stein-0/10 rounded-xs transition-colors"
aria-label={social.label ||
t(T.header_social_aria)}
onclick={closeMenu}
+18 -10
View File
@@ -45,32 +45,40 @@
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
});
const paginationLinkClass =
" bg-linear-to-b from-stein-50 to-stein-100 rounded-full h-6 w-6 mx-[2px] flex justify-center items-center text-stein-950 no-underline text-xs font-medium border border-stein-200 shadow-md";
const baseShape =
"rounded-xs h-8 mx-[2px] flex justify-center items-center no-underline text-sm font-medium border transition-colors";
const inactiveColors =
"text-stein-700 border-stein-200 bg-white hover:bg-stein-50 hover:border-wald-300";
const activeColors =
"text-white border-wald-500 bg-wald-500 hover:bg-wald-600 hover:border-wald-600 pointer-events-none";
const numberShape = "min-w-8 px-2";
const navShape = "px-3 gap-1";
</script>
{#if showPagination}
<div class="inline-flex py-4">
<div class="flex">
<nav class="inline-flex py-4 items-center" aria-label="Seitennavigation">
<div class="flex items-center">
{#if hasPrev}
<a href={pageHref(prevPage)} class={paginationLinkClass} aria-label={t(T.pagination_prev)}>
<Icon icon="mdi:chevron-left" class="text-xs" aria-hidden="true" />
<a href={pageHref(prevPage)} class="{baseShape} {navShape} {inactiveColors}" aria-label={t(T.pagination_prev)}>
<Icon icon="mdi:chevron-left" class="size-4" aria-hidden="true" />
<span class="hidden sm:inline">{t(T.pagination_prev)}</span>
</a>
{/if}
{#each pageNumbers as num}
<a
href={pageHref(num)}
class="{paginationLinkClass} {num === currentPage ? 'opacity-50 shadow-none' : ''}"
class="{baseShape} {numberShape} {num === currentPage ? activeColors : inactiveColors}"
aria-current={num === currentPage ? 'page' : undefined}
>
{num}
</a>
{/each}
{#if hasNext}
<a href={pageHref(nextPage)} class={paginationLinkClass} aria-label={t(T.pagination_next)}>
<Icon icon="mdi:chevron-right" class="text-xs" aria-hidden="true" />
<a href={pageHref(nextPage)} class="{baseShape} {navShape} {inactiveColors}" aria-label={t(T.pagination_next)}>
<span class="hidden sm:inline">{t(T.pagination_next)}</span>
<Icon icon="mdi:chevron-right" class="size-4" aria-hidden="true" />
</a>
{/if}
</div>
</div>
</nav>
{/if}
+6 -6
View File
@@ -154,19 +154,19 @@
onclick={onCommentClick}
aria-label={t(T.comments_jump_to)}
title={t(T.comments_jump_to)}
class="no-underline! inline-flex items-center gap-1 rounded-full border border-zinc-200 bg-white px-2.5 py-1 text-xs font-medium text-zinc-700! hover:bg-zinc-50 hover:border-zinc-300 transition-colors"
class="no-underline! inline-flex items-center gap-1 rounded-full border border-stein-200 bg-white px-2.5 py-1 text-xs font-medium text-stein-700! hover:bg-stein-50 hover:border-stein-300 transition-colors"
>
<Icon icon="mdi:comment-outline" class="size-3.5" />
<span class="tabular-nums">{commentCount ?? "…"}</span>
</a>
{/if}
<div class="inline-flex items-center rounded-full border border-zinc-200 bg-white overflow-hidden divide-x divide-zinc-200 print:hidden">
<div class="inline-flex items-center rounded-full border border-stein-200 bg-white overflow-hidden divide-x divide-stein-200 print:hidden">
{#if canShare}
<button
type="button"
onclick={share}
class="inline-flex items-center px-2.5 py-1 text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 transition-colors"
class="inline-flex items-center px-2.5 py-1 text-stein-600 hover:bg-stein-50 hover:text-stein-900 transition-colors"
aria-label={t(T.post_action_share)}
title={t(T.post_action_share)}
>
@@ -179,7 +179,7 @@
<button
type="button"
onclick={copyLink}
class="inline-flex items-center px-2.5 py-1 text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 transition-colors"
class="inline-flex items-center px-2.5 py-1 text-stein-600 hover:bg-stein-50 hover:text-stein-900 transition-colors"
aria-label={copied ? t(T.post_action_copied) : t(T.post_action_copy)}
title={copied ? t(T.post_action_copied) : t(T.post_action_copy)}
>
@@ -188,7 +188,7 @@
<button
type="button"
onclick={print}
class="inline-flex items-center px-2.5 py-1 text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 transition-colors"
class="inline-flex items-center px-2.5 py-1 text-stein-600 hover:bg-stein-50 hover:text-stein-900 transition-colors"
aria-label={t(T.post_action_print)}
title={t(T.post_action_print)}
>
@@ -198,7 +198,7 @@
{#if readingTimeMinutes != null && readingTimeMinutes > 0}
<span
class="inline-flex items-center gap-1 rounded-full border border-zinc-200 bg-white px-2.5 py-1 text-xs text-zinc-500"
class="inline-flex items-center gap-1 rounded-full border border-stein-200 bg-white px-2.5 py-1 text-xs text-stein-500"
title={t(T.post_action_reading_time, { minutes: readingTimeMinutes })}
>
<Icon icon="mdi:clock-outline" class="size-3.5" />
+4 -4
View File
@@ -59,7 +59,7 @@
layout="post"
class={isPastEvent ? "opacity-70 grayscale" : ""}
>
<div class="relative aspect-3/2 w-full overflow-hidden bg-gray-100">
<div class="relative aspect-3/2 w-full overflow-hidden bg-stein-100">
{#if rawImg}
<RustyImage
src={rawImg}
@@ -79,7 +79,7 @@
loading="lazy"
/>
{:else}
<div class="w-full h-full flex items-center justify-center text-gray-300">
<div class="w-full h-full flex items-center justify-center text-stein-300">
<svg xmlns="http://www.w3.org/2000/svg" class="size-12" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/>
</svg>
@@ -92,7 +92,7 @@
{/if}
{#if isPastEvent}
<div class="absolute top-2 right-2">
<span class="inline-flex items-center gap-1 rounded-full bg-neutral-800/90 px-2.5 py-1 text-[.65rem] font-semibold uppercase tracking-wide text-white shadow-sm">
<span class="inline-flex items-center gap-1 rounded-full bg-stein-800/90 px-2.5 py-1 text-[.65rem] font-semibold uppercase tracking-wide text-white shadow-sm">
Vergangen
</span>
</div>
@@ -100,7 +100,7 @@
{#if commentCount != null}
<div class="absolute top-2 left-2">
<span
class="inline-flex items-center gap-1 rounded-full bg-white/90 px-2 py-1 text-[.65rem] font-semibold tabular-nums text-zinc-700 shadow-sm"
class="inline-flex items-center gap-1 rounded-full bg-white/90 px-2 py-1 text-[.65rem] font-semibold tabular-nums text-stein-700 shadow-sm"
aria-label={t(T.comments_count_aria, { count: commentCount })}
title={t(T.comments_count_aria, { count: commentCount })}
>
+14 -14
View File
@@ -89,7 +89,7 @@
<div class="container-custom py-4 overflow-auto max-h-[calc(100vh-120px)]">
<label class="relative block max-w-xl mx-auto">
<span class="sr-only">Suche</span>
<span class="pointer-events-none absolute top-1/2 left-3 -translate-y-1/2 text-zinc-500">
<span class="pointer-events-none absolute top-1/2 left-3 -translate-y-1/2 text-stein-500">
<Icon icon="mdi:magnify" class="h-5 w-5" />
</span>
<input
@@ -97,14 +97,14 @@
type="search"
bind:value={query}
placeholder="Seiten und Beiträge durchsuchen…"
class="w-full rounded-sm border border-zinc-300 bg-white py-3 pl-10 pr-10 text-sm focus:border-zinc-500 focus:outline-none"
class="w-full rounded-xs border border-stein-300 bg-white py-3 pl-10 pr-10 text-sm focus:border-stein-500 focus:outline-none"
/>
{#if query}
<button
type="button"
onclick={() => (query = "")}
aria-label="Eingabe leeren"
class="absolute top-1/2 right-2 -translate-y-1/2 rounded-sm p-1 text-zinc-500 hover:bg-zinc-100 hover:text-zinc-900"
class="absolute top-1/2 right-2 -translate-y-1/2 rounded-xs p-1 text-stein-500 hover:bg-stein-100 hover:text-stein-900"
>
<Icon icon="mdi:close" class="h-4 w-4" />
</button>
@@ -113,36 +113,36 @@
<div class="max-w-xl mx-auto mt-4 text-sm">
{#if loading}
<p class="text-zinc-500 text-center py-2">Lade Suchindex…</p>
<p class="text-stein-500 text-center py-2">Lade Suchindex…</p>
{:else if loadError}
<p class="text-red-600 text-center py-2">Suche nicht verfügbar: {loadError}</p>
<p class="text-fire-600 text-center py-2">Suche nicht verfügbar: {loadError}</p>
{:else if normalizedQuery.length < 2}
<p class="text-zinc-500 text-center py-2">Mindestens 2 Zeichen eingeben.</p>
<p class="text-stein-500 text-center py-2">Mindestens 2 Zeichen eingeben.</p>
{:else if results.length === 0}
<p class="text-zinc-500 text-center py-2">Keine Treffer.</p>
<p class="text-stein-500 text-center py-2">Keine Treffer.</p>
{:else}
<ul class="divide-y divide-zinc-200">
<ul class="divide-y divide-stein-200">
{#each results as hit}
<li>
<a
href={hit.href}
onclick={closeSearch}
class="flex items-start gap-3 py-3 hover:bg-zinc-50 rounded-sm px-2 -mx-2 no-underline"
class="flex items-start gap-3 py-3 hover:bg-stein-50 rounded-xs px-2 -mx-2 no-underline"
>
{#if hit.image}
<img
src={hit.image}
alt=""
class="w-20 h-12 object-cover shrink-0 rounded-sm border border-zinc-200"
class="w-20 h-12 object-cover shrink-0 rounded-xs border border-stein-200"
loading="lazy"
/>
{:else}
<span class="w-20 h-12 shrink-0 bg-zinc-100 rounded-sm border border-zinc-200 flex items-center justify-center text-zinc-400">
<span class="w-20 h-12 shrink-0 bg-stein-100 rounded-xs border border-stein-200 flex items-center justify-center text-stein-400">
<Icon icon={hit.type === "post" ? "mdi:file-document-outline" : "mdi:file-outline"} class="h-5 w-5" />
</span>
{/if}
<div class="min-w-0 flex-1">
<div class="flex items-center gap-2 text-[.65rem] uppercase tracking-wide text-zinc-500">
<div class="flex items-center gap-2 text-[.65rem] uppercase tracking-wide text-stein-500">
<span>{hit.type === "post" ? "Beitrag" : "Seite"}</span>
{#if hit.isEvent && hit.eventDate}
<span class="text-wald-700">{formatDate(hit.eventDate)}</span>
@@ -150,9 +150,9 @@
<span>{formatDate(hit.created)}</span>
{/if}
</div>
<div class="font-medium text-zinc-900 truncate">{hit.title}</div>
<div class="font-medium text-stein-900 truncate">{hit.title}</div>
{#if hit.excerpt}
<div class="text-xs text-zinc-600 line-clamp-2">{hit.excerpt}</div>
<div class="text-xs text-stein-600 line-clamp-2">{hit.excerpt}</div>
{/if}
</div>
</a>
+2 -2
View File
@@ -62,7 +62,7 @@
if (variant === "white")
return "bg-stein-100 text-stein-800";
if (variant === "green") return "bg-wald-100 text-wald-800";
if (variant === "blue") return "bg-sky-100/90 text-sky-900";
if (variant === "blue") return "bg-himmel-100/90 text-himmel-900";
if (variant === "inactive") return "bg-stein-200 text-stein-500";
if (variant === "date") return "bg-wald-50 text-wald-800";
return "bg-stein-200 text-stein-500";
@@ -71,7 +71,7 @@
const c = customColor?.trim();
if (!c) return "";
const light = isLightBackground(c);
const fg = light ? "#111827" : "#fafafa";
const fg = light ? "var(--color-stein-900)" : "var(--color-stein-50)";
return `background-color: ${c}; color: ${fg};`;
});
const interactiveClass = $derived.by(() =>
+6 -6
View File
@@ -97,7 +97,7 @@
<div class="w-full">
{#if hasImage}
<div
class="w-full overflow-hidden relative flex justify-center items-center shadow-lg bg-zinc-200"
class="w-full overflow-hidden relative flex justify-center items-center shadow-lg bg-stein-200"
style={wrapperStyle}
>
{#if hasResponsive && responsive}
@@ -144,7 +144,7 @@
<div class="absolute inset-0 flex items-center justify-start ">
<div class="container-custom mx-auto px-6 relative">
{#if headlineHtml}
<h1 class="bg-red-400/70 inline-block py-1 px-2 -ml-2 backdrop-blur">{@html headlineHtml}</h1>
<h1 class="bg-fire-400/70 inline-block py-1 px-2 -ml-2 backdrop-blur">{@html headlineHtml}</h1>
{/if}
<div></div>
{#if subheadlineHtml}
@@ -155,17 +155,17 @@
{/if}
</div>
{:else if hasPageTitle}
<div class="border-b border-zinc-200 container mx-auto px-6 py-4">
<div class="border-b border-stein-200 container mx-auto px-6 py-4">
{#if headlineHtml}
<h1 class="text-2xl font-bold text-zinc-900">{@html headlineHtml}</h1>
<h1 class="text-2xl font-bold text-stein-900">{@html headlineHtml}</h1>
{/if}
{#if subheadlineHtml}
<h2 class="text-lg text-zinc-600 mt-1">{@html subheadlineHtml}</h2>
<h2 class="text-lg text-stein-600 mt-1">{@html subheadlineHtml}</h2>
{/if}
</div>
{/if}
{#if hasText}
<div class="w-full bg-green-700 text-white text-center py-2 px-4">
<div class="w-full bg-wald-700 text-white text-center py-2 px-4">
<div class="container mx-auto">
<div class="text-sm font-medium">{banner!.text}</div>
</div>
@@ -243,7 +243,7 @@
<div class="flex items-center justify-between gap-2 mb-4">
<button
type="button"
class="p-2 rounded-md text-himmel-100 hover:bg-himmel-700 hover:text-himmel-50 transition-colors"
class="p-2 rounded-xs text-himmel-100 hover:bg-himmel-700 hover:text-himmel-50 transition-colors"
aria-label={t(T.calendar_prev_month)}
onclick={prevMonth}
>
@@ -255,7 +255,7 @@
>
<button
type="button"
class="p-2 rounded-md text-himmel-100 hover:bg-himmel-700 hover:text-himmel-50 transition-colors"
class="p-2 rounded-xs text-himmel-100 hover:bg-himmel-700 hover:text-himmel-50 transition-colors"
aria-label={t(T.calendar_next_month)}
onclick={nextMonth}
>
@@ -280,7 +280,7 @@
{#if hasEvents}
<button
type="button"
class="relative aspect-square rounded-md flex flex-col items-center justify-center min-w-0 transition-colors cursor-pointer {isCurrentMonth
class="relative aspect-square rounded-xs flex flex-col items-center justify-center min-w-0 transition-colors cursor-pointer {isCurrentMonth
? 'text-himmel-100 hover:bg-himmel-700'
: 'text-himmel-100 opacity-60 hover:opacity-80'} bg-himmel-700/50 font-semibold hover:bg-himmel-600 {isSelected
? 'ring-2 ring-himmel-400 bg-himmel-600'
@@ -297,7 +297,7 @@
</button>
{:else}
<div
class="relative aspect-square rounded-md flex flex-col items-center justify-center min-w-0 cursor-default {isCurrentMonth
class="relative aspect-square rounded-xs flex flex-col items-center justify-center min-w-0 cursor-default {isCurrentMonth
? 'text-himmel-100'
: 'text-himmel-100 opacity-50'}"
>
@@ -81,9 +81,9 @@
const variantClasses = $derived(
variant === "urgent"
? "bg-amber-100 text-amber-900"
? "bg-erde-100 text-erde-900"
: variant === "info"
? "bg-sky-100 text-sky-900"
? "bg-himmel-100 text-himmel-900"
: "bg-wald-500 text-wald-50",
);
const iconName = $derived(
@@ -101,14 +101,14 @@
{#snippet inner()}
<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 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 rounded-xs 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-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"
class="ml-0 inline-flex min-w-0 max-w-0 scale-[0.96] items-center overflow-hidden whitespace-nowrap rounded-xs 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>
+7 -7
View File
@@ -111,27 +111,27 @@
<h3 class="mb-3 text-lg font-semibold">{block.headline}</h3>
{/if}
{#if block.description}
<p class="mb-3 text-sm text-zinc-700">{block.description}</p>
<p class="mb-3 text-sm text-stein-700">{block.description}</p>
{/if}
{#if resolved.length === 0}
<p class="text-sm text-zinc-500">Keine Dateien verfügbar.</p>
<p class="text-sm text-stein-500">Keine Dateien verfügbar.</p>
{:else}
<ul class="flex flex-col gap-2 list-none! p-0 m-0! ml-0">
{#each resolved as f}
<li class="list-none! ml-0">
<a
href={f.href}
class="group flex items-start gap-3 rounded-md border border-zinc-200 bg-white px-3 py-2 hover:border-zinc-400 hover:bg-zinc-50 transition-colors"
class="group flex items-start gap-3 rounded-xs border border-stein-200 bg-white px-3 py-2 hover:border-stein-400 hover:bg-stein-50 transition-colors"
target="_blank"
rel="noopener noreferrer"
>
<Icon icon={f.iconName} class="size-6 shrink-0 text-zinc-600" aria-hidden="true" />
<Icon icon={f.iconName} class="size-6 shrink-0 text-stein-600" aria-hidden="true" />
<span class="flex flex-col min-w-0">
<span class="font-medium text-zinc-900 group-hover:underline truncate">{f.label}</span>
<span class="font-medium text-stein-900 group-hover:underline truncate">{f.label}</span>
{#if f.description}
<span class="text-sm text-zinc-600">{f.description}</span>
<span class="text-sm text-stein-600">{f.description}</span>
{/if}
<span class="text-xs text-zinc-500">
<span class="text-xs text-stein-500">
{#if f.ext}<span class="uppercase">{f.ext}</span>{/if}
{#if f.ext && f.sizeLabel} · {/if}
{#if f.sizeLabel}{f.sizeLabel}{/if}
+3 -3
View File
@@ -34,7 +34,7 @@
<div class={layoutClasses} data-block-type="iframe" data-block-slug={block._slug}>
{#if src}
<div class="relative aspect-video w-full overflow-hidden rounded-sm bg-zinc-100">
<div class="relative aspect-video w-full overflow-hidden rounded-xs bg-stein-100">
<iframe
title={block.content ?? "Embed"}
src={src}
@@ -46,7 +46,7 @@
<div
role="button"
tabindex="0"
class="absolute inset-0 z-10 cursor-pointer rounded-sm bg-black/50 flex items-center justify-center"
class="absolute inset-0 z-10 cursor-pointer rounded-xs bg-black/50 flex items-center justify-center"
aria-label={t(T.iframe_activate_aria)}
onclick={activateMap}
onkeydown={(e) => e.key === "Enter" && activateMap()}
@@ -62,6 +62,6 @@
{/if}
</div>
{:else}
<p class="text-sm text-zinc-500">{t(T.iframe_missing)}</p>
<p class="text-sm text-stein-500">{t(T.iframe_missing)}</p>
{/if}
</div>
+3 -3
View File
@@ -50,14 +50,14 @@
quality={85}
fit="contain"
alt={block.caption ?? title ?? ""}
class="w-full rounded-sm"
class="w-full rounded-xs"
loading="lazy"
/>
{#if block.caption}
<figcaption class="mt-1 text-sm text-zinc-600">{block.caption}</figcaption>
<figcaption class="mt-1 text-sm text-stein-600">{block.caption}</figcaption>
{/if}
</figure>
{:else}
<p class="text-sm text-zinc-500">Bild nicht verfügbar.</p>
<p class="text-sm text-stein-500">Bild nicht verfügbar.</p>
{/if}
</div>
@@ -174,7 +174,7 @@
<li class="m-0 p-0">
<button
type="button"
class="group relative block w-full aspect-square overflow-hidden rounded-sm bg-wald-100 p-2 cursor-zoom-in focus:outline-none focus:ring-2 focus:ring-wald-500"
class="group relative block w-full aspect-square overflow-hidden rounded-xs bg-wald-100 p-2 cursor-zoom-in focus:outline-none focus:ring-2 focus:ring-wald-500"
onclick={() => openModal(i)}
aria-label={label || t(T.image_gallery_open_aria)}
>
@@ -220,7 +220,7 @@
<img
src={cur.url}
alt={curLabel}
class="max-h-[80vh] max-w-full rounded-sm bg-stein-900 object-contain shadow-2xl"
class="max-h-[80vh] max-w-full rounded-xs bg-stein-900 object-contain shadow-2xl"
loading="eager"
/>
<div class="flex w-full items-center justify-between gap-3 text-white">
@@ -281,7 +281,7 @@
fit="cover"
quality={80}
alt={withUrl[0].img.description ?? ""}
class="w-full rounded-sm object-cover aspect-video"
class="w-full rounded-xs object-cover aspect-video"
loading="eager"
/>
{#if withUrl[0].img.description}
@@ -291,7 +291,7 @@
{:else}
<div class="group relative">
<div
class="relative overflow-hidden rounded-sm bg-stein-100 aspect-video touch-pan-y cursor-grab active:cursor-grabbing"
class="relative overflow-hidden rounded-xs bg-stein-100 aspect-video touch-pan-y cursor-grab active:cursor-grabbing"
role="region"
aria-label={t(T.image_gallery_swipe_aria)}
onpointerdown={onPointerDown}
@@ -64,7 +64,7 @@
{#snippet defaultCard(o: OrganisationEntry, linkUrl: string | undefined, logoField: ReturnType<typeof organisationLogoField>, orgIndex: number)}
<Card href={linkUrl} class="h-full">
<div class="flex h-11 w-11 shrink-0 items-center justify-center overflow-hidden bg-gray-100">
<div class="flex h-11 w-11 shrink-0 items-center justify-center overflow-hidden bg-stein-100">
{#if logoField}
<RustyImage
src={logoField.url}
@@ -79,7 +79,7 @@
/>
{:else}
{@const fishMaskId = `org-logo-fallback-mask-${orgIndex}`}
<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">
<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">
<defs>
<mask id={fishMaskId}>
<g fill="none">
@@ -98,9 +98,9 @@
<Badge color={o.badge.color}>{o.badge.label}</Badge>
</div>
{/if}
<h5 class="mb-1 min-w-0 truncate text-sm font-medium leading-tight text-slate-950">{o.name ?? ""}</h5>
<h5 class="mb-1 min-w-0 truncate text-sm font-medium leading-tight text-stein-900">{o.name ?? ""}</h5>
{#if o.description}
<p class="line-clamp-2 text-xs font-light text-slate-600">{o.description}</p>
<p class="line-clamp-2 text-xs font-light text-stein-600">{o.description}</p>
{/if}
</Card>
{/snippet}
@@ -204,7 +204,7 @@
{@const logoField = organisationLogoField(o)}
{#if compact}
<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">
<div class="flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden bg-stein-100">
{#if logoField}
<RustyImage
src={logoField.url}
@@ -219,7 +219,7 @@
/>
{:else}
{@const fishMaskId = `org-logo-fallback-mask-c-${orgIndex}`}
<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">
<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">
<defs>
<mask id={fishMaskId}>
<g fill="none">
@@ -234,9 +234,9 @@
{/if}
</div>
<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>
<h5 class="text-sm font-medium leading-tight text-stein-900">{o.name ?? ""}</h5>
{#if o.description}
<p class="line-clamp-2 text-xs font-light text-slate-600">{o.description}</p>
<p class="line-clamp-2 text-xs font-light text-stein-600">{o.description}</p>
{/if}
</div>
</Card>
@@ -76,7 +76,7 @@
{#if posts.length > 0}
<div class="mt-3 text-xs px-2">
<a href="/posts/" class="inline-flex items-center gap-1 text-zinc-700 hover:text-zinc-900 hover:underline !no-underline">
<a href="/posts/" class="inline-flex items-center gap-1 text-stein-700 hover:text-stein-900 hover:underline !no-underline">
{t(T.post_overview_all)}
<span aria-hidden="true"></span>
</a>
+3 -3
View File
@@ -13,14 +13,14 @@
const alignClass = $derived(
isCenter ? "text-center" : block.variant === "right" ? "text-right" : "text-left",
);
const borderClass = $derived(isCenter ? "" : "border-l-4 border-green-700 pl-4");
const borderClass = $derived(isCenter ? "" : "border-l-4 border-wald-700 pl-4");
</script>
{#snippet quoteMarkup()}
<blockquote class="{borderClass} {alignClass} {extraClass}">
<p class="text-lg text-zinc-700 mb-2! ">"{block.quote ?? ""}"</p>
<p class="text-lg text-stein-700 mb-2! ">"{block.quote ?? ""}"</p>
{#if block.author}
<cite class="mt-1 block not-italic text-xs text-zinc-400">{block.author}</cite>
<cite class="mt-1 block not-italic text-xs text-stein-400">{block.author}</cite>
{/if}
</blockquote>
{/snippet}
@@ -81,7 +81,7 @@
{/if}
{#if quotes.length === 0}
<p class="text-sm text-zinc-500 italic">Keine Zitate vorhanden.</p>
<p class="text-sm text-stein-500 italic">Keine Zitate vorhanden.</p>
{:else}
<div class="flex items-center gap-1.5 sm:gap-2">
{#if showArrows && quotes.length > 1}
@@ -89,7 +89,7 @@
type="button"
onclick={prev}
aria-label="Vorheriges Zitat"
class="shrink-0 inline-flex items-center justify-center size-7 rounded-full bg-white/90 border border-zinc-200 shadow-sm hover:bg-white hover:border-green-700 transition"
class="shrink-0 inline-flex items-center justify-center size-7 rounded-full bg-white/90 border border-stein-200 shadow-sm hover:bg-white hover:border-wald-700 transition"
>
<Icon icon="mdi:chevron-left" class="size-4" aria-hidden="true" />
</button>
@@ -113,7 +113,7 @@
type="button"
onclick={next}
aria-label="Nächstes Zitat"
class="shrink-0 inline-flex items-center justify-center size-7 rounded-full bg-white/90 border border-zinc-200 shadow-sm hover:bg-white hover:border-green-700 transition"
class="shrink-0 inline-flex items-center justify-center size-7 rounded-full bg-white/90 border border-stein-200 shadow-sm hover:bg-white hover:border-wald-700 transition"
>
<Icon icon="mdi:chevron-right" class="size-4" aria-hidden="true" />
</button>
@@ -130,8 +130,8 @@
aria-label={`Zitat ${i + 1}`}
onclick={() => goTo(i)}
class="size-2 rounded-full transition-colors {i === index
? 'bg-green-700'
: 'bg-zinc-300 hover:bg-zinc-400'}"
? 'bg-wald-700'
: 'bg-stein-300 hover:bg-stein-400'}"
></button>
{/each}
</div>
@@ -184,7 +184,7 @@
<Tooltip content={helpTooltipText} placement="top">
<button
type="button"
class="shrink-0 p-1.5 rounded-md text-himmel-500 hover:text-himmel-700 hover:bg-himmel-50 transition-colors focus:outline-none focus:ring-2 focus:ring-wald-500 focus:ring-offset-1"
class="shrink-0 p-1.5 rounded-xs text-himmel-500 hover:text-himmel-700 hover:bg-himmel-50 transition-colors focus:outline-none focus:ring-2 focus:ring-wald-500 focus:ring-offset-1"
aria-label={t(T.searchable_text_help_aria)}
>
<Icon
@@ -197,7 +197,7 @@
<input
type="search"
placeholder={t(T.searchable_text_placeholder)}
class="w-full text-sm px-4 py-2.5 pr-10 border border-stein-200 rounded-md focus:outline-none focus:ring-2 focus:ring-wald-500 focus:border-wald-400 bg-stein-0 text-stein-900 placeholder:text-stein-400"
class="w-full text-sm px-4 py-2.5 pr-10 border border-stein-200 rounded-xs focus:outline-none focus:ring-2 focus:ring-wald-500 focus:border-wald-400 bg-stein-0 text-stein-900 placeholder:text-stein-400"
bind:value={searchQuery}
oninput={(e) => (searchQuery = (e.target as HTMLInputElement).value)}
aria-label={t(T.searchable_text_search_aria)}
@@ -205,7 +205,7 @@
{#if searchQuery}
<button
type="button"
class="absolute right-9 top-1/2 -translate-y-1/2 p-1.5 rounded-md hover:bg-stein-200 text-stein-500 hover:text-stein-700 transition-colors"
class="absolute right-9 top-1/2 -translate-y-1/2 p-1.5 rounded-xs hover:bg-stein-200 text-stein-500 hover:text-stein-700 transition-colors"
onclick={() => (searchQuery = "")}
aria-label={t(T.searchable_text_clear_search)}
>
@@ -290,7 +290,7 @@
<div class="flex justify-end mb-3 -mt-1">
<button
type="button"
class="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded-md border border-stein-200 bg-stein-50 text-stein-700 hover:bg-wald-50 hover:border-wald-200 hover:text-wald-800 transition-colors"
class="inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium rounded-xs border border-stein-200 bg-stein-50 text-stein-700 hover:bg-wald-50 hover:border-wald-200 hover:text-wald-800 transition-colors"
onclick={(e) => {
e.preventDefault();
copyFragmentContent(fragment, i);
@@ -129,7 +129,7 @@
);
}
function fmtPrice(eurMwh: number | null): string {
if (eurMwh == null) return "";
if (eurMwh == null) return "·";
return Math.round(eurMwh).toLocaleString("de-DE") + " €/MWh";
}
function fmtTime(unix: number | null): string {
@@ -244,7 +244,7 @@
<svelte:element
this={explanationHref ? "a" : "div"}
href={explanationHref || undefined}
class="block rounded-md border border-l-4 bg-white shadow-sm transition-colors {accentClasses.box} {explanationHref ? 'no-underline! hover:brightness-95' : ''}"
class="block rounded-xs border border-l-4 bg-white shadow-sm transition-colors {accentClasses.box} {explanationHref ? 'no-underline! hover:brightness-95' : ''}"
>
<div class="flex flex-wrap items-center gap-x-4 gap-y-1 px-4 py-3 text-sm">
{#if !live}
@@ -252,7 +252,7 @@
{:else}
{#if compactInner.pct != null}
{#key live.measuredAtUnix}
<span class="strommix-pct text-3xl sm:text-4xl font-extrabold tabular-nums leading-none {accentClasses.pct}">
<span class="strommix-pct text-3xl sm:text-4xl font-bold tabular-nums leading-none {accentClasses.pct}">
{compactInner.pct}%
</span>
{/key}
@@ -331,7 +331,7 @@
<!-- Main: percentage + status -->
{#if loadError}
<div class="p-6 text-sm text-red-700">
<div class="p-6 text-sm text-fire-700">
{t(T.strommix_load_error, { error: loadError })}
</div>
{:else if !live}
@@ -347,7 +347,7 @@
supports it. -->
{#key live.measuredAtUnix}
<div
class="strommix-pct text-7xl sm:text-8xl font-extrabold tabular-nums leading-none {accentClasses.pct}"
class="strommix-pct text-7xl sm:text-8xl font-bold tabular-nums leading-none {accentClasses.pct}"
>
{Math.round(renewablePct)}%
</div>
@@ -477,7 +477,7 @@
{t(T.strommix_check_values)}
</summary>
<div
class="mt-2 grid grid-cols-2 gap-x-4 gap-y-1 rounded-md border border-stein-200 bg-stein-50 px-3 py-2 tabular-nums sm:grid-cols-3"
class="mt-2 grid grid-cols-2 gap-x-4 gap-y-1 rounded-xs border border-stein-200 bg-stein-50 px-3 py-2 tabular-nums sm:grid-cols-3"
>
<div class="text-stein-500">
{t(T.strommix_field_wind_onshore)}
@@ -86,7 +86,7 @@
<div class={layoutClasses} data-block-type="youtube_video" data-block-slug={block._slug}>
{#if hasEmbed}
<div class="aspect-video w-full overflow-hidden rounded-sm bg-stein-100">
<div class="aspect-video w-full overflow-hidden rounded-xs bg-stein-100">
<iframe
title={block.title ?? t(T.youtube_title_fallback)}
src={embedUrl}
@@ -169,7 +169,7 @@
<li class="m-0 p-0">
<button
type="button"
class="group relative block w-full aspect-video overflow-hidden rounded-sm bg-stein-100 cursor-pointer focus:outline-none focus:ring-2 focus:ring-wald-500"
class="group relative block w-full aspect-video overflow-hidden rounded-xs bg-stein-100 cursor-pointer focus:outline-none focus:ring-2 focus:ring-wald-500"
onclick={() => openModal(i)}
aria-label={label || t(T.youtube_title_fallback)}
>
@@ -222,7 +222,7 @@
onclick={(e) => e.stopPropagation()}
role="presentation"
>
<div class="aspect-video w-full overflow-hidden rounded-sm bg-black">
<div class="aspect-video w-full overflow-hidden rounded-xs bg-black">
{#key modalIndex}
<iframe
title={curLabel || t(T.youtube_title_fallback)}
@@ -280,7 +280,7 @@
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
{#key currentIndex}
{@const current = items[currentIndex]}
<div class="aspect-video w-full overflow-hidden rounded-sm bg-stein-100" transition:fade={{ duration: 150 }}>
<div class="aspect-video w-full overflow-hidden rounded-xs bg-stein-100" transition:fade={{ duration: 150 }}>
<iframe
title={current.video.title ?? t(T.youtube_title_fallback)}
src={current.embedUrl}
@@ -291,7 +291,7 @@
></iframe>
</div>
{#if second}
<div class="hidden md:block aspect-video w-full overflow-hidden rounded-sm bg-stein-100" transition:fade={{ duration: 150 }}>
<div class="hidden md:block aspect-video w-full overflow-hidden rounded-xs bg-stein-100" transition:fade={{ duration: 150 }}>
<iframe
title={second.video.title ?? t(T.youtube_title_fallback)}
src={second.embedUrl}
@@ -81,6 +81,12 @@
"transmission-tower": {
"body": "<path fill=\"currentColor\" d=\"m8.28 5.45l-1.78-.9L7.76 2h8.47l1.27 2.55l-1.78.89L15 4H9zM18.62 8h-4.53l-.79-3h-2.6l-.79 3H5.38L4.1 10.55l1.79.89l.73-1.44h10.76l.72 1.45l1.79-.89zm-.85 14H15.7l-.24-.9L12 15.9l-3.47 5.2l-.23.9H6.23l2.89-11h2.07l-.36 1.35L12 14.1l1.16-1.75l-.35-1.35h2.07zm-6.37-7l-.9-1.35l-1.18 4.48zm3.28 3.12l-1.18-4.48l-.9 1.36z\"/>"
},
"database-outline": {
"body": "<path fill=\"currentColor\" d=\"M12 3C7.58 3 4 4.79 4 7v10c0 2.21 3.59 4 8 4s8-1.79 8-4V7c0-2.21-3.58-4-8-4m6 14c0 .5-2.13 2-6 2s-6-1.5-6-2v-2.23c1.61.78 3.72 1.23 6 1.23s4.39-.45 6-1.23zm0-4.55c-1.3.95-3.58 1.55-6 1.55s-4.7-.6-6-1.55V9.64c1.47.83 3.61 1.36 6 1.36s4.53-.53 6-1.36zM12 9C8.13 9 6 7.5 6 7s2.13-2 6-2s6 1.5 6 2s-2.13 2-6 2\"/>"
},
"alert-circle": {
"body": "<path fill=\"currentColor\" d=\"M13 13h-2V7h2m0 10h-2v-2h2M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2\"/>"
},
"cloud-off-outline": {
"body": "<path fill=\"currentColor\" d=\"M19.8 22.6L17.15 20H6.5q-2.3 0-3.9-1.6T1 14.5q0-1.92 1.19-3.42q1.19-1.51 3.06-1.93q.08-.2.15-.39q.1-.19.15-.41L1.4 4.2l1.4-1.4l18.4 18.4M6.5 18h8.65L7.1 9.95q-.05.28-.07.55q-.03.23-.03.5h-.5q-1.45 0-2.47 1.03Q3 13.05 3 14.5T4.03 17q1.02 1 2.47 1m15.1.75l-1.45-1.4q.43-.35.64-.81T21 15.5q0-1.05-.73-1.77q-.72-.73-1.77-.73H17v-2q0-2.07-1.46-3.54Q14.08 6 12 6q-.67 0-1.3.16q-.63.17-1.2.52L8.05 5.23q.88-.6 1.86-.92Q10.9 4 12 4q2.93 0 4.96 2.04Q19 8.07 19 11q1.73.2 2.86 1.5q1.14 1.28 1.14 3q0 1-.37 1.81q-.38.84-1.03 1.44m-6.77-6.72\"/>"
},
+1 -1
View File
@@ -10,7 +10,7 @@
} = $props();
const baseClass =
'inline-flex shrink-0 whitespace-nowrap rounded-full py-1 px-2.5 text-[0.6875rem] font-medium transition-all ring-1 no-underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1';
'inline-flex shrink-0 whitespace-nowrap rounded-full py-1 px-2.5 text-[0.6875rem] font-medium transition-colors ring-1 no-underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1';
const variantClasses = $derived(
{
+1 -1
View File
@@ -74,7 +74,7 @@
{#if showTooltip}
<div
role="tooltip"
class="absolute z-50 {placementClasses} px-3 py-2 text-xs font-normal text-stein-0 bg-stein-800 rounded-md shadow-lg min-w-56 max-w-88 text-center pointer-events-none whitespace-normal"
class="absolute z-50 {placementClasses} px-3 py-2 text-xs font-normal text-stein-0 bg-stein-800 rounded-xs shadow-lg min-w-56 max-w-88 text-center pointer-events-none whitespace-normal"
style={horizontalStyle}
>
{content}
+6 -6
View File
@@ -17,27 +17,27 @@
<section>
<div class="container-custom pt-10 text-center">
<p class="mt-6 text-7xl md:text-8xl font-extrabold tracking-tight text-wald-700">{status}</p>
<h1 class="mt-3 text-2xl md:text-3xl font-semibold text-zinc-900">
<p class="mt-6 text-7xl md:text-8xl font-bold tracking-tight text-wald-700">{status}</p>
<h1 class="mt-3 text-2xl md:text-3xl font-semibold text-stein-900">
{isNotFound ? t('page_404_title') : `Fehler ${status}`}
</h1>
{#if isNotFound}
<p class="mx-auto mt-4 max-w-xl text-base text-zinc-600">{t('page_404_text')}</p>
<p class="mx-auto mt-4 max-w-xl text-base text-stein-600">{t('page_404_text')}</p>
{:else if message}
<p class="mx-auto mt-4 max-w-xl text-base text-zinc-600">{message}</p>
<p class="mx-auto mt-4 max-w-xl text-base text-stein-600">{message}</p>
{/if}
<div class="mt-8 flex flex-wrap items-center justify-center gap-3">
<a
href="/"
class="inline-flex items-center gap-2 rounded-sm bg-wald-700 px-5 py-2.5 text-sm font-medium text-white hover:bg-wald-800 no-underline"
class="btn-primary inline-flex items-center gap-2 text-sm font-medium"
>
<Icon icon="mdi:home-outline" class="h-4 w-4" />
{t('page_404_back')}
</a>
<a
href="/posts/"
class="inline-flex items-center gap-2 rounded-sm border border-zinc-300 bg-white px-5 py-2.5 text-sm font-medium text-zinc-700 hover:bg-zinc-100 no-underline"
class="btn-secondary inline-flex items-center gap-2 text-sm font-medium"
>
<Icon icon="mdi:file-document-outline" class="h-4 w-4" />
Zu den Beiträgen
+4 -4
View File
@@ -271,18 +271,18 @@
<TranslationProvider translations={data.translations}>
<a
href="#main-content"
class="sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-[100] focus:bg-white focus:px-3 focus:py-2 focus:shadow focus:outline focus:outline-2 focus:outline-wald-600 focus:rounded-sm"
class="sr-only focus:not-sr-only focus:fixed focus:top-2 focus:left-2 focus:z-[100] focus:bg-white focus:px-3 focus:py-2 focus:shadow focus:outline focus:outline-2 focus:outline-wald-600 focus:rounded-xs"
>Zum Inhalt springen</a>
<div class="flex min-h-screen flex-col text-zinc-900">
<div class="flex min-h-screen flex-col text-stein-900">
{#if pageData?.preview || pageData?.previewDraft}
<div
class="sticky top-0 z-[90] w-full bg-amber-500 text-black shadow-sm"
class="sticky top-0 z-[90] w-full bg-erde-500 text-black shadow-sm"
role="status"
aria-live="polite"
>
<div class="container-custom flex items-center justify-between gap-3 py-1.5 text-sm">
<span class="font-semibold">
{pageData?.previewDraft ? 'Live-Preview ungespeicherter Draft' : 'Preview-Modus Draft sichtbar (nicht indexiert)'}
{pageData?.previewDraft ? 'Live-Preview · ungespeicherter Draft' : 'Preview-Modus · Draft sichtbar (nicht indexiert)'}
</span>
<a
href={$page.url.pathname}
+3 -3
View File
@@ -26,10 +26,10 @@
<li>
<a
href={'/' + ((p.slug ?? p._slug ?? '').replace(/^\//, '').trim() || '').split('/').filter(Boolean).map(encodeURIComponent).join('/')}
class="block rounded-sm border border-zinc-200 bg-white px-4 py-3 shadow-sm transition hover:border-green-700/30 hover:shadow"
class="block rounded-xs border border-stein-200 bg-white px-4 py-3 shadow-sm transition hover:border-wald-700/30 hover:shadow"
>
<span class="font-medium text-zinc-900">{p.linkName ?? p.name ?? p.slug ?? p._slug}</span>
{#if p.headline}<span class="mt-1 block text-sm text-zinc-500">{p.headline}</span>{/if}
<span class="font-medium text-stein-900">{p.linkName ?? p.name ?? p.slug ?? p._slug}</span>
{#if p.headline}<span class="mt-1 block text-sm text-stein-500">{p.headline}</span>{/if}
</a>
</li>
{/each}
+2 -2
View File
@@ -107,7 +107,7 @@
<h1 class="p-name">{data.post.headline}</h1>
{/if}
{#if data.post.subheadline}
<p class="text-zinc-600 lead p-summary">{data.post.subheadline}</p>
<p class="text-stein-600 lead p-summary">{data.post.subheadline}</p>
{/if}
</header>
{/if}
@@ -172,7 +172,7 @@
lazy
class="mt-6"
>
<div class="p-8 border border-zinc-200 rounded-lg">
<div class="p-8 border border-stein-200 rounded-lg">
<Comments pageId={data.commentPageId} />
</div>
</Accordion>
+1 -1
View File
@@ -19,7 +19,7 @@
</div>
<div class="content mt-8">
{#if data.cmsError}
<div class="rounded-sm border border-amber-200 bg-amber-50 p-4 text-amber-800">
<div class="rounded-xs border border-erde-200 bg-erde-50 p-4 text-erde-800">
<strong>{t(data.translations, T.posts_cms_error)}</strong> {data.cmsError}
</div>
{:else}
+1 -1
View File
@@ -19,7 +19,7 @@
</div>
<div class="content mt-8">
{#if data.cmsError}
<div class="rounded-sm border border-amber-200 bg-amber-50 p-4 text-amber-800">
<div class="rounded-xs border border-erde-200 bg-erde-50 p-4 text-erde-800">
<strong>{t(data.translations, T.posts_cms_error)}</strong> {data.cmsError}
</div>
{:else}
+1 -1
View File
@@ -19,7 +19,7 @@
</div>
<div class="content mt-8">
{#if data.cmsError}
<div class="rounded-sm border border-amber-200 bg-amber-50 p-4 text-amber-800">
<div class="rounded-xs border border-erde-200 bg-erde-50 p-4 text-erde-800">
<strong>{t(data.translations, T.posts_cms_error)}</strong> {data.cmsError}
</div>
{:else}
@@ -19,7 +19,7 @@
</div>
<div class="content mt-8">
{#if data.cmsError}
<div class="rounded-sm border border-amber-200 bg-amber-50 p-4 text-amber-800">
<div class="rounded-xs border border-erde-200 bg-erde-50 p-4 text-erde-800">
<strong>{t(data.translations, T.posts_cms_error)}</strong> {data.cmsError}
</div>
{:else}