feat(stellungnahme): a11y, Suche, Frist-Status, Steckbrief & Map mobil
Deploy / verify (push) Successful in 57s
Deploy / deploy (push) Successful in 1m38s

- Titel klickbar als <label> (Tastatur/Screenreader), aria-live auf Ausgabe
- Neustart mit Rückfrage, mailto-Längen-Guard (>1900 Zeichen)
- Frist-abgelaufen-Banner statt kommentarlos verschwinden
- Suchfeld filtert allgemeine Argumente live
- <details>-Chevron dreht beim Aufklappen
- Steckbrief einklappbar + scrollbar, Single-Newlines als Hard-Break
- Mini-Map responsive Höhe (h-56 mobil → h-80 desktop)
- Ausgabe-Buttons text-sm/text-[11px], mobil umbrechend; Mail-Link no-underline
- gebietsBez-Deklaration vor Verwendung gezogen (svelte-check Fehler)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Peter Meier
2026-05-28 14:41:43 +02:00
parent 5d0a634359
commit 0be73adc51
2 changed files with 86 additions and 21 deletions
@@ -87,6 +87,25 @@
return Array.from(map.values()); return Array.from(map.values());
}); });
// Quick-filter for allgemeine arguments (matches title / text / bulletPoints)
let argFilter = $state("");
const filteredGruppen = $derived.by((): Group[] => {
const q = argFilter.trim().toLowerCase();
if (!q) return allgemeineGruppen;
return allgemeineGruppen
.map((g) => ({
...g,
items: g.items.filter((f) => {
const hay = [f.title, f.text, ...(f.bulletPoints ?? [])]
.filter(Boolean)
.join(" ")
.toLowerCase();
return hay.includes(q);
}),
}))
.filter((g) => g.items.length > 0);
});
// ── localStorage ──────────────────────────────────────────────────────────── // ── localStorage ────────────────────────────────────────────────────────────
const storageKey = `stellungnahme:${block._slug ?? block.id ?? "default"}`; const storageKey = `stellungnahme:${block._slug ?? block.id ?? "default"}`;
const historyKey = `${storageKey}:history`; const historyKey = `${storageKey}:history`;
@@ -146,6 +165,12 @@
argNotes = { ...argNotes, [slug]: value }; argNotes = { ...argNotes, [slug]: value };
} }
const gebietsBez = $derived(
windArea
? `${windArea.gebiets_nr}${windArea.bezeichnung ? " " + windArea.bezeichnung : ""}`
: "",
);
// Editable opening/closing — null = use reactive default // Editable opening/closing — null = use reactive default
const defaultOpening = $derived( const defaultOpening = $derived(
block.defaultOpeningText block.defaultOpeningText
@@ -218,18 +243,14 @@ Regionale Planungsstelle
Karl-Liebknecht-Straße 4 Karl-Liebknecht-Straße 4
98527 Suhl`; 98527 Suhl`;
const gebietsBez = $derived(
windArea
? `${windArea.gebiets_nr}${windArea.bezeichnung ? " " + windArea.bezeichnung : ""}`
: "",
);
const mailtoLink = $derived.by(() => { const mailtoLink = $derived.by(() => {
if (!outputText) return ""; if (!outputText) return "";
const subject = `Einwendung Regionalplan Südwestthüringen Vorranggebiet ${gebietsBez}`; const subject = `Einwendung Regionalplan Südwestthüringen Vorranggebiet ${gebietsBez}`;
const to = block.recipientEmail ?? ""; const to = block.recipientEmail ?? "";
return `mailto:${to}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(outputText)}`; return `mailto:${to}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(outputText)}`;
}); });
// mailto-URLs >~2000 Zeichen werden von manchen Clients (Outlook/Windows) abgeschnitten
const mailTooLong = $derived(mailtoLink.length > 1900);
function buildText(): string { function buildText(): string {
const heute = new Date().toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" }); const heute = new Date().toLocaleDateString("de-DE", { day: "2-digit", month: "2-digit", year: "numeric" });
@@ -299,6 +320,9 @@ ${"=".repeat(64)}`;
} }
function resetAll() { function resetAll() {
if (typeof window !== "undefined" && !window.confirm("Alle Eingaben und ausgewählten Argumente löschen und neu beginnen?")) {
return;
}
selectedSlugs = new Set(); selectedSlugs = new Set();
expandedItems = new Set(); expandedItems = new Set();
expandedGroups = new Set(); expandedGroups = new Set();
@@ -470,6 +494,11 @@ ${"=".repeat(64)}`;
{:else}— noch {deadlineDays} Tage {:else}— noch {deadlineDays} Tage
{/if} {/if}
</span> </span>
</div>
{:else if deadlineDays !== null && deadlineDays < 0}
<div class="mb-4 flex items-center gap-3 rounded-lg border border-stein-300 bg-stein-100 px-4 py-3 text-sm font-medium text-stein-600">
<Icon icon="mdi:clock-remove-outline" class="size-5 shrink-0" />
<span>Einwendungsfrist abgelaufen ({deadlineFormatted}). Eine Einreichung ist möglicherweise nicht mehr möglich.</span>
</div> </div>
{/if} {/if}
@@ -575,13 +604,19 @@ ${"=".repeat(64)}`;
</div> </div>
{/if} {/if}
</dl> </dl>
{#if windArea.notizen} {#if windArea.notizen}
<details class="mt-4 border-t border-wald-200 pt-3">
<summary class="flex cursor-pointer items-center gap-1 text-sm font-medium text-wald-700 list-none">
<Icon icon="mdi:chevron-down" class="det-chevron size-4" />
Steckbrief des Gebiets
</summary>
<div class="prose prose-sm prose-stein mt-2 max-h-72 max-w-none overflow-y-auto rounded-lg bg-white/60 p-3 text-sm text-stein-700">{@html md(windArea.notizen.replace(/\n/g, " \n"))}</div>
</details> </details>
{/if} {/if}
</div> </div>
<!-- Mini-map --> <!-- Mini-map -->
{#if browser && MapComponent && mapReady && mapAreaData.length > 0} {#if browser && MapComponent && mapReady && mapAreaData.length > 0}
<div class="relative mb-6 h-56 overflow-hidden rounded-xl border border-stein-200 shadow-sm sm:h-80"> <div class="relative mb-6 h-56 overflow-hidden rounded-xl border border-stein-200 shadow-sm sm:h-80">
{#await MapComponent then Map} {#await MapComponent then Map}
<Map <Map
@@ -626,7 +661,7 @@ ${"=".repeat(64)}`;
Sie wählen zuerst ortskonkrete Argumente für Ihr Gebiet, dann allgemeine Einwände. Sie wählen zuerst ortskonkrete Argumente für Ihr Gebiet, dann allgemeine Einwände.
</p> </p>
<div class="flex flex-wrap items-center gap-3"> <div class="flex flex-wrap items-center gap-3">
<button <button
class="rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800 disabled:opacity-40" class="rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800 disabled:opacity-40"
disabled={!windArea} disabled={!windArea}
onclick={() => goTo(1)} onclick={() => goTo(1)}
@@ -651,6 +686,7 @@ ${"=".repeat(64)}`;
{#each kriterien as k} {#each kriterien as k}
<div class="rounded-lg border transition-colors {selectedSlugs.has(k._slug) ? 'border-wald-400 bg-wald-50' : 'border-stein-200 bg-white'}"> <div class="rounded-lg border transition-colors {selectedSlugs.has(k._slug) ? 'border-wald-400 bg-wald-50' : 'border-stein-200 bg-white'}">
<div class="flex items-start gap-3 p-3"> <div class="flex items-start gap-3 p-3">
<input
id="chk-ort-{k._slug}" id="chk-ort-{k._slug}"
type="checkbox" type="checkbox"
class="mt-0.5 h-4 w-4 shrink-0 rounded accent-wald-700" class="mt-0.5 h-4 w-4 shrink-0 rounded accent-wald-700"
@@ -658,7 +694,7 @@ ${"=".repeat(64)}`;
onchange={() => toggleSlug(k._slug)} onchange={() => toggleSlug(k._slug)}
/> />
<div class="min-w-0 flex-1"> <div class="min-w-0 flex-1">
<div class="flex items-center justify-between gap-2"> <div class="flex items-center justify-between gap-2">
<label for="chk-ort-{k._slug}" class="cursor-pointer font-medium text-stein-800">{k.title ?? k._slug.replace(/_/g, " ")}</label> <label for="chk-ort-{k._slug}" class="cursor-pointer font-medium text-stein-800">{k.title ?? k._slug.replace(/_/g, " ")}</label>
{#if k.text} {#if k.text}
<button <button
@@ -694,7 +730,7 @@ ${"=".repeat(64)}`;
{/if} {/if}
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<button class="rounded-lg border border-stein-300 px-4 py-2 text-sm text-stein-600 hover:bg-stein-50" onclick={() => goTo(0)}> Zurück</button> <button class="rounded-lg border border-stein-300 px-4 py-2 text-sm text-stein-600 hover:bg-stein-50" onclick={() => goTo(0)}> Zurück</button>
<button class="rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800" onclick={() => goTo(2)}> <button class="rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800" onclick={() => goTo(2)}>
Weiter{ortskonkreteSelectedCount > 0 ? ` (${ortskonkreteSelectedCount} gewählt)` : ""} Weiter{ortskonkreteSelectedCount > 0 ? ` (${ortskonkreteSelectedCount} gewählt)` : ""}
</button> </button>
@@ -716,11 +752,24 @@ ${"=".repeat(64)}`;
<p class="mb-4 text-xs text-stein-400">Aus Schritt 2: keine ortskonkreten Argumente ausgewählt.</p> <p class="mb-4 text-xs text-stein-400">Aus Schritt 2: keine ortskonkreten Argumente ausgewählt.</p>
{/if} {/if}
{#if allgemeineGruppen.length > 0}
<div class="relative mb-3">
<Icon icon="mdi:magnify" class="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-stein-400" />
<input
type="search"
class="w-full rounded-lg border border-stein-300 py-2 pl-9 pr-3 text-sm text-stein-800 focus:border-wald-500 focus:outline-none focus:ring-2 focus:ring-wald-200"
placeholder="Argumente durchsuchen …"
bind:value={argFilter}
aria-label="Argumente durchsuchen"
/>
</div>
{#if filteredGruppen.length === 0}
<p class="mb-6 rounded-lg border border-stein-200 bg-stein-50 px-4 py-3 text-sm text-stein-500">Keine Argumente passen zu „{argFilter}".</p>
{/if} {/if}
<div class="mb-6 space-y-2"> <div class="mb-6 space-y-2">
{#each filteredGruppen as group} {#each filteredGruppen as group}
{@const groupSelectedCount = group.items.filter((f) => selectedSlugs.has(f._slug)).length} {@const groupSelectedCount = group.items.filter((f) => selectedSlugs.has(f._slug)).length}
{@const allSelected = groupSelectedCount === group.items.length} {@const allSelected = groupSelectedCount === group.items.length}
{@const isExpanded = expandedGroups.has(group.slug) || argFilter.trim() !== ""} {@const isExpanded = expandedGroups.has(group.slug) || argFilter.trim() !== ""}
<div class="rounded-lg border {groupSelectedCount > 0 ? 'border-stein-400' : 'border-stein-200'} overflow-hidden"> <div class="rounded-lg border {groupSelectedCount > 0 ? 'border-stein-400' : 'border-stein-200'} overflow-hidden">
<!-- Group header --> <!-- Group header -->
@@ -752,6 +801,7 @@ ${"=".repeat(64)}`;
{#each group.items as f} {#each group.items as f}
<div class="transition-colors {selectedSlugs.has(f._slug) ? 'bg-wald-50' : 'bg-white'}"> <div class="transition-colors {selectedSlugs.has(f._slug) ? 'bg-wald-50' : 'bg-white'}">
<div class="flex items-start gap-3 px-3 py-2.5"> <div class="flex items-start gap-3 px-3 py-2.5">
<input
id="chk-allg-{f._slug}" id="chk-allg-{f._slug}"
type="checkbox" type="checkbox"
class="mt-0.5 h-4 w-4 shrink-0 rounded accent-wald-700" class="mt-0.5 h-4 w-4 shrink-0 rounded accent-wald-700"
@@ -759,7 +809,7 @@ ${"=".repeat(64)}`;
onchange={() => toggleSlug(f._slug)} onchange={() => toggleSlug(f._slug)}
/> />
<div class="min-w-0 flex-1"> <div class="min-w-0 flex-1">
<div class="flex items-center justify-between gap-2"> <div class="flex items-center justify-between gap-2">
<label for="chk-allg-{f._slug}" class="cursor-pointer text-sm font-medium text-stein-800">{f.title ?? f._slug.replace(/_/g, " ")}</label> <label for="chk-allg-{f._slug}" class="cursor-pointer text-sm font-medium text-stein-800">{f.title ?? f._slug.replace(/_/g, " ")}</label>
{#if f.text} {#if f.text}
<button <button
@@ -800,7 +850,7 @@ ${"=".repeat(64)}`;
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<button class="rounded-lg border border-stein-300 px-4 py-2 text-sm text-stein-600 hover:bg-stein-50" onclick={() => goTo(1)}> Zurück</button> <button class="rounded-lg border border-stein-300 px-4 py-2 text-sm text-stein-600 hover:bg-stein-50" onclick={() => goTo(1)}> Zurück</button>
<button <button
class="rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800 disabled:opacity-40" class="rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800 disabled:opacity-40"
disabled={selectedFragments.length === 0} disabled={selectedFragments.length === 0}
onclick={() => goTo(3)} onclick={() => goTo(3)}
@@ -830,7 +880,7 @@ ${"=".repeat(64)}`;
></textarea> ></textarea>
<p class="mt-1 text-xs text-stein-400">Bleibt auf Ihrem Gerät. Wird nicht übertragen.</p> <p class="mt-1 text-xs text-stein-400">Bleibt auf Ihrem Gerät. Wird nicht übertragen.</p>
<div class="mt-5 flex items-center gap-3"> <div class="mt-5 flex items-center gap-3">
<button class="rounded-lg border border-stein-300 px-4 py-2 text-sm text-stein-600 hover:bg-stein-50" onclick={() => goTo(2)}> Zurück</button> <button class="rounded-lg border border-stein-300 px-4 py-2 text-sm text-stein-600 hover:bg-stein-50" onclick={() => goTo(2)}> Zurück</button>
<button class="rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800" onclick={() => goTo(4)}>Weiter →</button> <button class="rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800" onclick={() => goTo(4)}>Weiter →</button>
</div> </div>
</div> </div>
@@ -865,7 +915,7 @@ ${"=".repeat(64)}`;
<div class="mb-4 space-y-2"> <div class="mb-4 space-y-2">
<details class="rounded-lg border border-stein-200 overflow-hidden"> <details class="rounded-lg border border-stein-200 overflow-hidden">
<summary class="flex cursor-pointer items-center justify-between bg-stein-50 px-4 py-2.5 text-sm font-medium text-stein-700 hover:bg-stein-100 list-none"> <summary class="flex cursor-pointer items-center justify-between bg-stein-50 px-4 py-2.5 text-sm font-medium text-stein-700 hover:bg-stein-100 list-none">
<span>Einleitung anpassen</span> <span>Einleitung anpassen</span>
<Icon icon="mdi:chevron-down" class="det-chevron size-4 text-stein-400" /> <Icon icon="mdi:chevron-down" class="det-chevron size-4 text-stein-400" />
</summary> </summary>
<div class="border-t border-stein-100 px-4 py-3"> <div class="border-t border-stein-100 px-4 py-3">
@@ -882,7 +932,7 @@ ${"=".repeat(64)}`;
</details> </details>
<details class="rounded-lg border border-stein-200 overflow-hidden"> <details class="rounded-lg border border-stein-200 overflow-hidden">
<summary class="flex cursor-pointer items-center justify-between bg-stein-50 px-4 py-2.5 text-sm font-medium text-stein-700 hover:bg-stein-100 list-none"> <summary class="flex cursor-pointer items-center justify-between bg-stein-50 px-4 py-2.5 text-sm font-medium text-stein-700 hover:bg-stein-100 list-none">
<span>Abschluss anpassen</span> <span>Abschluss anpassen</span>
<Icon icon="mdi:chevron-down" class="det-chevron size-4 text-stein-400" /> <Icon icon="mdi:chevron-down" class="det-chevron size-4 text-stein-400" />
</summary> </summary>
<div class="border-t border-stein-100 px-4 py-3"> <div class="border-t border-stein-100 px-4 py-3">
@@ -901,7 +951,7 @@ ${"=".repeat(64)}`;
<div class="mb-2 flex gap-3"> <div class="mb-2 flex gap-3">
<button class="rounded-lg border border-stein-300 px-4 py-2 text-sm text-stein-600 hover:bg-stein-50" onclick={() => goTo(3)}> Zurück</button> <button class="rounded-lg border border-stein-300 px-4 py-2 text-sm text-stein-600 hover:bg-stein-50" onclick={() => goTo(3)}> Zurück</button>
<button <button
class="btn-wiggle rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800 disabled:opacity-40" class="btn-wiggle rounded-lg bg-wald-700 px-5 py-2.5 text-sm font-semibold text-white transition hover:bg-wald-800 disabled:opacity-40"
disabled={!absenderName.trim()} disabled={!absenderName.trim()}
onclick={generateOutput} onclick={generateOutput}
@@ -913,19 +963,22 @@ ${"=".repeat(64)}`;
<div class="mb-4"></div> <div class="mb-4"></div>
{/if} {/if}
{#if showOutput} {#if showOutput}
<div class="rounded-xl border border-wald-300 bg-white shadow-sm" role="region" aria-live="polite" aria-label="Generierte Einwendung"> <div class="rounded-xl border border-wald-300 bg-white shadow-sm" role="region" aria-live="polite" aria-label="Generierte Einwendung">
<div class="flex flex-col gap-2 border-b border-wald-200 px-4 py-3 sm:flex-row sm:items-center sm:justify-between"> <div class="flex flex-col gap-2 border-b border-wald-200 px-4 py-3 sm:flex-row sm:items-center sm:justify-between">
<span class="text-sm font-semibold text-wald-800">Ihre Einwendung</span> <span class="text-sm font-semibold text-wald-800">Ihre Einwendung</span>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<button class="rounded-md border border-stein-300 px-2.5 py-1 text-[11px] font-medium text-stein-700 hover:bg-stein-50" onclick={copyText}>{copyFeedback || "Kopieren"}</button> <button class="rounded-md border border-stein-300 px-2.5 py-1 text-[11px] font-medium text-stein-700 hover:bg-stein-50" onclick={copyText}>{copyFeedback || "Kopieren"}</button>
<button class="rounded-md border border-stein-300 px-2.5 py-1 text-[11px] font-medium text-stein-700 hover:bg-stein-50" onclick={downloadText}>Herunterladen</button> <button class="rounded-md border border-stein-300 px-2.5 py-1 text-[11px] font-medium text-stein-700 hover:bg-stein-50" onclick={downloadText}>Herunterladen</button>
<button class="rounded-md border border-stein-300 px-2.5 py-1 text-[11px] font-medium text-stein-700 hover:bg-stein-50" onclick={printText}>Drucken</button> <button class="rounded-md border border-stein-300 px-2.5 py-1 text-[11px] font-medium text-stein-700 hover:bg-stein-50" onclick={printText}>Drucken</button>
{#if mailtoLink && !mailTooLong} {#if mailtoLink && !mailTooLong}
<a href={mailtoLink} class="rounded-md border border-wald-400 bg-wald-50 px-2.5 py-1 text-[11px] font-medium text-wald-700 no-underline hover:bg-wald-100">{block.recipientEmail ? "Per E-Mail senden" : "Per E-Mail (an mich)"}</a> <a href={mailtoLink} class="rounded-md border border-wald-400 bg-wald-50 px-2.5 py-1 text-[11px] font-medium text-wald-700 no-underline hover:bg-wald-100">{block.recipientEmail ? "Per E-Mail senden" : "Per E-Mail (an mich)"}</a>
{/if} {/if}
</div> </div>
</div> </div>
<div class="overflow-x-auto whitespace-pre-wrap break-words px-5 py-4 font-sans text-sm leading-relaxed text-stein-800">{outputText}</div>
{#if mailTooLong}
<div class="border-t border-stein-100 px-5 py-2 text-xs text-stein-500">Für E-Mail zu lang — bitte <strong>Kopieren</strong> und in die Mail einfügen.</div>
{/if} {/if}
</div> </div>
<div class="mt-4 rounded-lg border border-himmel-200 bg-himmel-50 px-4 py-3 text-sm text-himmel-800"> <div class="mt-4 rounded-lg border border-himmel-200 bg-himmel-50 px-4 py-3 text-sm text-himmel-800">
@@ -984,4 +1037,10 @@ ${"=".repeat(64)}`;
} }
.btn-wiggle:hover { .btn-wiggle:hover {
animation: none; animation: none;
}
:global(.det-chevron) {
transition: transform 0.2s ease;
}
details[open] :global(.det-chevron) {
transform: rotate(180deg);
} }
@@ -114,6 +114,12 @@
"content-copy": { "content-copy": {
"body": "<path fill=\"currentColor\" d=\"M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12z\"/>" "body": "<path fill=\"currentColor\" d=\"M19 21H8V7h11m0-2H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2m-3-4H4a2 2 0 0 0-2 2v14h2V3h12z\"/>"
}, },
"clock-alert-outline": {
"body": "<path fill=\"currentColor\" d=\"M11 7v6l5.2 3.1l.8-1.2l-4.5-2.7V7zm9 5v6h2v-6zm0 8v2h2v-2zm-2 0c-1.7 1.3-3.7 2-6 2c-5.5 0-10-4.5-10-10S6.5 2 12 2c4.8 0 8.9 3.4 9.8 8h-2.1c-.9-3.4-4-6-7.7-6c-4.4 0-8 3.6-8 8s3.6 8 8 8c2.4 0 4.5-1.1 6-2.7z\"/>"
},
"content-save-outline": {
"body": "<path fill=\"currentColor\" d=\"M17 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V7zm2 16H5V5h11.17L19 7.83zm-7-7c-1.66 0-3 1.34-3 3s1.34 3 3 3s3-1.34 3-3s-1.34-3-3-3M6 6h9v4H6z\"/>"
},
"transmission-tower": { "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\"/>" "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\"/>"
}, },