SvelteKits CSRF-Check blockte multipart-POSTs (/api/mitmachen) mit 403:
ORIGIN env stand auf www, Caddy redirected aber www -> non-www — jeder
Besucher war auf non-www, Origin-Header passte nie. Env-Flip auf non-www
(secrets), hier: www als trustedOrigin-Fallback + Kit-Bump auf ^2.65
(trustedOrigins gibt es ab 2.23).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- cleanText(): Zero-Width-/Bidi-Marks/BOM (Copy-Paste aus iOS/WhatsApp)
vor Validierung und im Payload entfernen — Telefonnummern mit
U+202D/U+202C fielen sonst durch die Validierung
- FormCard.svelte: gerahmter Container, umschließt Kontakt- und
Mitmachen-Formular
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ports the same loadPostImage + thumbBlock pattern from the calendar
social route. Reads postImage.src (fallback: image.src), loads via
CMS transform API as base64 JPEG, renders next to QR code.
Posts without an image are unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Social-Bild Calendar:
- Termin-Bild als Thumbnail neben QR-Code (Reihenfolge: QR | Bild)
- Wrapper transparent, Bild im natürlichen Aspect via object-fit:contain
und fit=inside auf transform-API — kein Crop, kein Letterbox
- Wachstum auf qrSize+28 begrenzt
- Title-Fontsize bei vorhandenem Thumb zusätzlich verkleinert
- Eckige Kanten (kein border-radius) für QR-Box und Thumb
Calendar-Block:
- Vorschaubild im Termin-Item gleich gerendert: object-contain,
max-w-24/max-h-24, kein Crop
- "Teilen"-Gruppe in Aktions-Toolbar bricht auf Mobile auf eigene
Zeile um, Trennstrich nur auf sm+ sichtbar
Direkt-Link:
- Calendar: /kalender/?social=<slug> öffnet Modal automatisch
- Post: /post/<slug>?social=1 öffnet Modal automatisch
- Modal-Header: "Direktlink"-Button kopiert URL ins Clipboard
Skeleton-Loader:
- Animierter grauer Skeleton während Bild-Render via satori
- Per Theme-Wechsel resetten, fade-in via opacity-Transition
- Story-Container Fix: explizite 280x158 Maße statt aspect-ratio
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Erklärt warum Anlagenzahl/Höhe-Schätzwerte entfernt wurden. Default
geschlossen, Chevron-Pfeil als Indikator zum Aufklappen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Beide Felder waren nicht belastbar (Schätzungen bzw. nicht final
festgelegt). Entfernt aus:
- Windkarte-Hover-Tooltip
- WindAreaPanel (Kenndaten + Export-Info)
- StellingnahmeGenerator-Steckbrief + Disclaimer-Footnote
Übrig: Fläche, Investor, Status. Genaue Anlagenzahl wird erst im
Genehmigungsverfahren bestimmt — keine vorausgreifende Vermittlung.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Windkarte-Tooltip:
- Auf Touch-Geräten (@media hover:none) ausgeblendet, Detail-Panel
öffnet eh bei Tap
- max-width 360px, min-width 220px, white-space:normal,
größeres padding/Schrift für bessere Lesbarkeit
- Anlagen-Zahl aus Tooltip entfernt (nicht belastbar)
- Gemeinden ungekürzt anzeigen, Truncate auf 3 entfernt
WindAreaPanel:
- "Anlagen geplant" nach unten verschoben (nach Investor), Zeile mit
opacity-60 + italic + mute-Farbe — zeigt visuell dass es nur eine
Schätzung ist
- Disclaimer-Text überarbeitet: Obergrenzen-Schätzung 2-3 Anlagen je
100 ha (270-Meter-Klasse) statt Faustregel 4-6
StellingnahmeGenerator: gleicher Disclaimer-Text-Wortlaut.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Label und Buttons jeder Gruppe (Kalender / Teilen / Anzeigen) in
eigene inline-flex-Container gekapselt. Umbruch passiert nur zwischen
Gruppen, Labels werden nicht mehr von ihren Buttons getrennt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Neuer Endpoint /api/social/post/[slug] mit gleichem Pattern wie für
Termine: Logo, Tag-Pill aus Title/Tags-Keywords (Presse, Demo,
Rückblick, Interview, Studie, Rechtlich, Meinung etc.), Datum,
Headline mit dynamischer Fontsize, Subheadline/Excerpt-Snippet, QR
zum Beitrag, Footer. 3 Formate × 3 Themes wie Kalender.
SocialImageModal in eigene wiederverwendbare Komponente extrahiert
und sowohl im PostActions als auch im CalendarBlock eingebunden.
PostActions akzeptiert socialSlug-Prop und blendet bei vorhandenem
Slug einen Modal-Trigger-Button neben den anderen Aktions-Icons ein.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Social-Bild-Endpoint:
- Logo aus page_config (gefärbt in Theme-Akzent) statt Wordmark
- Status-Pill (ONLINE/Demo/Info/Anhörung/Stammtisch/Sitzung) aus
Titel-Keywords und Tags, mit eigener Farbe
- Description-Snippet unter Titel (Square + Story)
- Story-Format 1080x1920 ergänzt
- Theme-Varianten: wald (default), transparent-onlight,
transparent-ondark
- Uhrzeit unter Datum (2. Zeile) mit Clock-Icon im Akzent-Grün
- QR linksbündig bei Square + Story, kleiner (180px)
- Location-Pin top-aligned, Title-Fontsize dynamisch bei langen Titeln
Neue Route /termin/[slug]: OG-Meta-Tags für Link-Previews
(FB/WhatsApp/Twitter), JS-Redirect zu /kalender/#event-<slug>.
QR-Code im Social-Bild zeigt jetzt auf /termin/[slug].
Calendar-Block Aktionen reorganisiert:
- Primary-Reihe: Mehr Info, Auf Karte, Anhang
- Kompakte Toolbar (gerahmt): Kalender (ICS, Google) | Teilen (Link,
Share, Bild) | Im Grid
- Theme-Selector im Social-Modal mit Vorschau-Hintergrund-Indikator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Single Button öffnet Vorschau-Modal mit beiden Formaten side-by-side.
Pro Format Download-Button. ESC + Click-outside schließen.
Endpoint generiert zusätzlich QR-Code (qrcode → PNG-Buffer), der
direkt auf den Termin im Kalender-Grid verweist
(/kalender/#event-<slug>). Pin-Icon, QR und Layout für OG (1200x630)
und Square (1080x1080).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Neuer Endpoint /api/social/calendar/[slug] rendert Termin via satori +
resvg zu PNG. Formate: og (1200x630) und square (1080x1080).
Gebrandetes Layout mit Datum, Titel, Ort. Inter-Font lazy von gstatic,
10min In-Memory-Cache pro Slug+Format.
CalendarBlock: zwei Download-Buttons pro Termin (Bild quer / quadr.).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Per-Status LayerGroups statt einer globalen labelLayer. syncLabels
respektiert hiddenStatuses und entfernt Labels für versteckte
Status-Kategorien beim Zoomen.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Marker-Klick zeigt jetzt zusätzlich Name, Rolle, Email und Telefon
der Kontaktpersonen pro Organisation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Neuer Block-Typ `organisations_map`: Leaflet-Karte mit CircleMarkern für alle
Organisationen die ein location.lat/lng haben. Klick auf Marker öffnet
Detail-Panel (Desktop: rechte Sidebar / Mobile: Bottom Sheet) mit Name,
Standort, Beschreibung und Website-Link.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Neue Felder whatsapp/youtube (string) auf OrganisationEntry.
OrganisationsCard zeigt Icon-Buttons wenn gesetzt.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Subheadlines in page headers and post cards support inline markdown
(bold, italic, links) via marked.parseInline.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- KI-Prompt kopieren mit Ton/Haltung-Slidern und persönlichem Hinweis
- Output-Textarea editierbar (field-sizing: content, auto-height)
- Stepper zeigt Füllstand: Haken (komplett), gelb (leer), grau (unbesucht)
- Weiter-Buttons mit Tooltips bei leerem Schritt
- Auto-Generate beim Betreten von Step 4, live bei Eingabe-Änderungen
- Drag & Drop Umsortierung der Argumente in Step 4
- Step in localStorage persistiert (HMR-Fix)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Filter:
- Tag-Pill-Reihe in Step 2 oberhalb der Suche. Multi-Select, OR-Logik
zwischen Pills, AND mit Text-Suche. Pills aus allen Nicht-Fetch-Tags
der deduplizierten Fragmente, alphabetisch sortiert. "Filter
zurücksetzen" erscheint bei ≥1 aktivem Pill. Empty-State erklärt
was nicht matcht (Text/Pills/beides).
Akkordeons raus (Variante B):
- Gruppen-Header bleiben als sichtbare Trenner (Label + Anzahl + "Alle"-
Toggle), aber Click-to-Expand-Mechanik weg — Items immer offen.
expandedGroups + toggleGroup als dead code entfernt.
Bedienkomfort:
- Sticky Mobile-Footer für alle 5 Step-Nav-Rows: bottom-2 mit
weißem BG + Shadow + Backdrop-Blur. Auf Desktop unverändert (sm:static).
- Auto-Save-Indikator "✓ Gespeichert" rechts oben, blitzt 2s nach
jeder Mutation. Pure UI — wir speichern eh schon in localStorage.
- Auto-Focus per Svelte-Action beim Step-Wechsel: Step 2 → Such-Input,
Step 3 → Betroffenheit-Textarea, Step 4 → Name-Input.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Step 0 (Gebietskontext):
- Gebiets-Nummer (W-37) deutlich größer: text-4xl tracking-tight
- Detail-Felder als Cards: rounded-lg border-wald-200 bg-white/70 p-3 shadow-sm
- Icons (Gemeinden, Fläche, Anlagen geplant, Max. Höhe, Investor, Status)
oben links als eigenes Element statt inline; size-5 text-wald-600
- Labels: text-sm sm:text-base font-semibold text-wald-800 whitespace-nowrap
(kleiner auf Mobile damit "Anlagen geplant" in der Card bleibt)
- Werte: text-stein-600 (grau) mit mt-1 Abstand
- Steckbrief-<details> default open
Step 2 (Allgemeine Argumente):
- "Weiter"-Button nicht mehr disabled bei 0 Auswahl — Mindest-Auswahl
weggefallen, Anzahl nur im Label wenn >0
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- layout.server.ts: NavLink um optional children?: NavLink[] erweitert.
navHeader-Resolve von 'links' auf 'all' (navgroup-sub-links werden mit
aufgelöst). Resolver-Loop erkennt navgroup-Entries (_type==='navgroup'
oder Shape label+links) und baut NavLink mit Children + Parent-URL.
- Header.svelte: Desktop-Dropdown mit Hover/Focus-Open + ARIA (haspopup,
expanded, role=menu/menuitem). Mobile: collapsible Submenu via
openSubmenu-State, slide-animiert; "– Übersicht"-Link wenn Parent
selbst eine URL hat. isActiveTree(): Parent gilt aktiv wenn ein Child
aktiv ist.
- Overflow-Fix: .gradient-blob-bg setzt overflow:hidden → clipte den
Desktop-Dropdown. Neue Variante .gradient-blob-bg-inner als absoluter
Inner-Layer (eigenes overflow-hidden), Header selbst bleibt
overflow-visible. Bestehende .gradient-blob-bg-Nutzungen (z.B.
DeadlineBannerBlock) unverändert.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>