Redesign SearchableTextBlock UI — stronger visual hierarchy
Deploy / verify (push) Successful in 56s
Deploy / deploy (push) Successful in 1m6s

Green gradient header, white card with shadow, left-border accent on open
accordion items, hover-visible copy button in summary row, lighter dividers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Peter Meier
2026-05-16 15:18:07 +02:00
parent 4fc541acf9
commit 5b4d59175b
2 changed files with 56 additions and 50 deletions
@@ -159,45 +159,43 @@
</script>
<div
class="searchable-text flex flex-col gap-0 border border-stein-200 bg-stein-50 {layoutClasses} {className}"
class="searchable-text flex flex-col gap-0 border border-stein-200 bg-white shadow-sm overflow-hidden {layoutClasses} {className}"
data-block="SearchableText" data-block-type="searchable_text"
data-block-slug={block._slug}
>
<div class="p-4 md:p-6">
{#if block.title}
<h2 class="text-xl md:text-2xl font-bold text-stein-900 mb-2">
{block.title}
</h2>
{/if}
{#if descriptionHtml}
<div class="markdown text-stein-600 max-w-none prose prose-zinc prose-sm">
{@html descriptionHtml}
</div>
{/if}
</div>
{#if block.title || descriptionHtml}
<div class="px-4 md:px-6 py-5 bg-gradient-to-br from-wald-700 to-wald-800">
{#if block.title}
<h2 class="text-xl md:text-2xl font-bold text-white mb-1">
{block.title}
</h2>
{/if}
{#if descriptionHtml}
<div class="markdown text-wald-100 max-w-none prose prose-sm prose-invert">
{@html descriptionHtml}
</div>
{/if}
</div>
{/if}
<header
class="sticky top-14 z-10 px-4 md:px-6 py-3 border-b border-stein-200 bg-stein-0/95 backdrop-blur-sm md:static md:bg-stein-100 md:backdrop-blur-none shadow-sm md:shadow-none"
class="sticky top-14 z-10 px-4 md:px-6 py-3 border-b border-stein-200 bg-white/95 backdrop-blur-sm shadow-sm"
>
<div class="flex flex-col gap-2">
<div class="relative flex items-center gap-2">
<Tooltip content={helpTooltipText} placement="top">
<button
type="button"
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"
class="shrink-0 p-1.5 rounded-xs text-stein-400 hover:text-wald-600 hover:bg-wald-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
icon="mdi:help-circle-outline"
class="size-5"
aria-hidden="true"
/>
<Icon icon="mdi:help-circle-outline" class="size-5" aria-hidden="true" />
</button>
</Tooltip>
<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-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"
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-white 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 +203,7 @@
{#if searchQuery}
<button
type="button"
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"
class="absolute right-9 top-1/2 -translate-y-1/2 p-1.5 rounded-xs hover:bg-stein-100 text-stein-400 hover:text-stein-700 transition-colors"
onclick={() => (searchQuery = "")}
aria-label={t(T.searchable_text_clear_search)}
>
@@ -219,8 +217,8 @@
/>
</div>
{#if allTags.length > 0}
<div class="overflow-x-auto -mx-1 px-1 pt-2 pb-2">
<div class="flex gap-2 flex-wrap min-w-max md:flex-wrap md:w-auto">
<div class="overflow-x-auto -mx-1 px-1 pt-1 pb-1">
<div class="flex gap-1.5 flex-wrap">
<Tag
label={t(T.searchable_text_tag_all)}
variant={selectedTag === "all" ? "green" : "white"}
@@ -242,7 +240,7 @@
</header>
<div
class="text-xs text-stein-600 px-4 md:px-6 py-2.5 bg-stein-100 border-b border-stein-200"
class="text-xs text-stein-500 px-4 md:px-6 py-2 bg-stein-50 border-b border-stein-100"
aria-live="polite"
>
{#if visibleFragments.length === 0}
@@ -259,11 +257,11 @@
{/if}
</div>
<div class="flex flex-col gap-0 bg-stein-100">
<div class="flex flex-col divide-y divide-stein-100">
{#each visibleFragments as fragment, i}
<details class="group border-b border-stein-200 last:border-b-0">
<details class="group border-l-4 border-l-transparent open:border-l-wald-500 transition-colors bg-white open:bg-wald-50/30">
<summary
class="cursor-pointer list-none px-4 md:px-6 py-3.5 bg-stein-50 hover:bg-wald-50 text-sm font-medium text-stein-800 flex flex-col gap-1.5 transition-colors"
class="cursor-pointer list-none px-4 md:px-6 py-3.5 hover:bg-wald-50/60 text-sm font-medium text-stein-800 flex flex-col gap-1.5 transition-colors"
>
<div class="flex items-start gap-2 min-w-0">
<div class="grow min-w-0">
@@ -272,11 +270,29 @@
searchQuery.trim(),
)}
</div>
<Icon
icon="mdi:chevron-down"
class="shrink-0 text-stein-500 group-open:rotate-180 transition-transform"
aria-hidden="true"
/>
<div class="shrink-0 flex items-center gap-2">
<button
type="button"
class="opacity-0 group-hover:opacity-100 inline-flex items-center gap-1 px-2 py-1 text-xs font-normal rounded-xs border border-stein-200 bg-white text-stein-600 hover:bg-wald-50 hover:border-wald-300 hover:text-wald-800 transition-all"
onclick={(e) => {
e.preventDefault();
copyFragmentContent(fragment, i);
}}
aria-label={t(T.searchable_text_copy_aria)}
tabindex="-1"
>
{#if copiedIndex === i}
<Icon icon="mdi:check" class="size-3.5 text-wald-600" aria-hidden="true" />
{:else}
<Icon icon="mdi:content-copy" class="size-3.5" aria-hidden="true" />
{/if}
</button>
<Icon
icon="mdi:chevron-down"
class="text-stein-400 group-open:rotate-180 transition-transform size-5"
aria-hidden="true"
/>
</div>
</div>
{#if fragment.tags.length > 0}
<span class="flex flex-wrap gap-1">
@@ -284,13 +300,11 @@
</span>
{/if}
</summary>
<div
class="px-4 md:px-6 py-4 bg-stein-0 markdown prose prose-zinc prose-sm max-w-none text-xs"
>
<div class="px-4 md:px-6 py-4 bg-white border-t border-stein-100 markdown prose prose-zinc prose-sm max-w-none text-xs">
<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-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"
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-300 hover:text-wald-800 transition-colors"
onclick={(e) => {
e.preventDefault();
copyFragmentContent(fragment, i);
@@ -298,18 +312,10 @@
aria-label={t(T.searchable_text_copy_aria)}
>
{#if copiedIndex === i}
<Icon
icon="mdi:check"
class="size-4 text-wald-600"
aria-hidden="true"
/>
<Icon icon="mdi:check" class="size-4 text-wald-600" aria-hidden="true" />
<span>{t(T.searchable_text_copied)}</span>
{:else}
<Icon
icon="mdi:content-copy"
class="size-4"
aria-hidden="true"
/>
<Icon icon="mdi:content-copy" class="size-4" aria-hidden="true" />
<span>{t(T.searchable_text_copy_button)}</span>
{/if}
</button>
+3 -3
View File
@@ -24,6 +24,9 @@
"rss": {
"body": "<path fill=\"currentColor\" d=\"M6.18 15.64a2.18 2.18 0 0 1 2.18 2.18C8.36 19 7.38 20 6.18 20C5 20 4 19 4 17.82a2.18 2.18 0 0 1 2.18-2.18M4 4.44A15.56 15.56 0 0 1 19.56 20h-2.83A12.73 12.73 0 0 0 4 7.27zm0 5.66a9.9 9.9 0 0 1 9.9 9.9h-2.83A7.07 7.07 0 0 0 4 12.93z\"/>"
},
"chevron-left": {
"body": "<path fill=\"currentColor\" d=\"M15.41 16.58L10.83 12l4.58-4.59L14 6l-6 6l6 6z\"/>"
},
"pencil-outline": {
"body": "<path fill=\"currentColor\" d=\"m14.06 9l.94.94L5.92 19H5v-.92zm3.6-6c-.25 0-.51.1-.7.29l-1.83 1.83l3.75 3.75l1.83-1.83c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29m-3.6 3.19L3 17.25V21h3.75L17.81 9.94z\"/>"
},
@@ -57,9 +60,6 @@
"menu": {
"body": "<path fill=\"currentColor\" d=\"M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z\"/>"
},
"chevron-left": {
"body": "<path fill=\"currentColor\" d=\"M15.41 16.58L10.83 12l4.58-4.59L14 6l-6 6l6 6z\"/>"
},
"comment-outline": {
"body": "<path fill=\"currentColor\" d=\"M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29zm1-6v3.08L13.08 16H20V4H4v12z\"/>"
},