0ab2c58eb4
- Header desktop nav: social icons grouped in a wald-tinted pill with labels, active-state (aria-current + bold), opacity hover (no per-item bg) - Mobile overlay: social links as icon+label rows with active-state - Search button: lucide:search, icon-only - Migrate all icons mdi→lucide app-wide (234 refs); brand/language logos (google, whatsapp, mastodon, telegram, language-*) stay on mdi - generate-icons: emit mdi + lucide subsets; add @iconify-json/lucide - iconify-offline: register lucide collection - scripts/icon-map|validate|apply: reusable migration tooling Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
61 lines
1.9 KiB
Svelte
61 lines
1.9 KiB
Svelte
<!--
|
|
Reusable disclosure box for short collapsible info notes.
|
|
- `title` — always-visible summary line
|
|
- `body` — HTML rendered inside the panel ({@html})
|
|
- `variant` — colour palette without callers passing raw Tailwind:
|
|
stein → neutral data-disclaimer tone
|
|
amber → soft warning, used for uncertainty-flagged hints
|
|
- `open` — initial state; default closed
|
|
-->
|
|
<script lang="ts">
|
|
import Icon from "@iconify/svelte";
|
|
|
|
type Variant = "stein" | "amber";
|
|
|
|
let {
|
|
title,
|
|
body = "",
|
|
variant = "stein",
|
|
open = false,
|
|
iconName = "lucide:info",
|
|
}: {
|
|
title: string;
|
|
body?: string;
|
|
variant?: Variant;
|
|
open?: boolean;
|
|
iconName?: string;
|
|
} = $props();
|
|
|
|
const palettes = {
|
|
stein: {
|
|
container: "border-stein-200 bg-stein-50",
|
|
summary: "text-stein-700 hover:bg-stein-100",
|
|
icon: "text-stein-500",
|
|
body: "border-stein-200 text-stein-600",
|
|
},
|
|
amber: {
|
|
container: "border-amber-300 bg-amber-100/70",
|
|
summary: "text-amber-800 hover:bg-amber-200/70",
|
|
icon: "text-amber-700",
|
|
body: "border-amber-200 text-stein-700",
|
|
},
|
|
} as const;
|
|
|
|
const p = $derived(palettes[variant]);
|
|
</script>
|
|
|
|
<details class="info-accordion rounded-md border text-xs {p.container}" {open}>
|
|
<summary class="flex cursor-pointer items-center gap-1.5 px-3 py-1.5 font-medium leading-snug list-none {p.summary}">
|
|
<Icon icon={iconName} class="size-3.5 shrink-0 {p.icon}" />
|
|
<span class="flex-1">{title}</span>
|
|
<Icon icon="lucide:chevron-down" class="info-accordion-chevron size-3.5 shrink-0 transition-transform {p.icon}" />
|
|
</summary>
|
|
<div class="markdown prose prose-sm prose-zinc max-w-none border-t px-3 py-2 leading-relaxed {p.body}">{@html body}</div>
|
|
</details>
|
|
|
|
<style>
|
|
.info-accordion[open] :global(.info-accordion-chevron) {
|
|
transform: rotate(180deg);
|
|
}
|
|
</style>
|