- LinkListBlock: id+scroll-mt-24 -> Anker-Sprung moeglich
- Frist-CTA verlinkt auf #generatoren (springt direkt zur Liste)
- WindkarteBlock: Hinweis "Klicke dein Vorranggebiet" (Karte ist Picker)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PostActions: 🔊 Vorlesen liest Artikeltext (Titel+Body, versteckte Elemente
gefiltert), Toggle Pause/Weiter + Stop, deutsche Stimme, satzweise, stoppt
bei Seitenwechsel. Button erscheint nur wenn speechSynthesis verfügbar.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Body-Lock sperrt Seiten-Scroll; mobile-nav hatte overflow-hidden ohne
Höhe → auf Android nicht scrollbar. Jetzt max-h(100dvh-Header) +
overflow-y-auto + overscroll-contain.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gelb-Palette ins @theme (fixt auch bisher wirkungslose gelb-* Klassen im
Deadline-Banner), .btn-warning als wiederverwendbare Variante; Termin-melden-
Button nutzt sie statt inline-style/arbitrary utilities.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regel 6: Quellen/Normen/Aktenzeichen direkt im Fließtext benennen.
Regel 7: keine Verweise auf Anlagen/Anhänge — jeder Beleg muss vollständig
im Dokument selbst stehen (nichts wird beigefügt).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Hinweis dass Einsendungen einmal täglich bearbeitet und die fertige
Stellungnahme per E-Mail zurückgesendet werden; E-Mail als Pflichtfeld
markiert (required + Kennzeichnung), sent-Bestätigung entsprechend angepasst.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
generateOutput() setzt sendState/sendError auf idle, damit nach erfolgreichem
Senden ein neu erzeugter Brieftext nicht am stale "übermittelt"-Status hängt.
resetAll (Neustart) resettet die Sende-Felder weiterhin.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
single = immer untereinander, auto = breitenbasiert mehrspaltig ab >4.
Regionalplan-Generatorenliste (w1-w40) auf single.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- AnnouncementBanner: führendes **bold** rendert als roter Pill-Badge
- Header: Kalender/Adressbuch/Suche je eigene Pill statt geteiltem Container
- LinkListBlock: uppercase raus, >4 Links → 4er-Spalten ab sm
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Email field + submit button stacked on mobile (button full width below the
input) and side by side from sm up. The long "Newsletter abonnieren" button
was squeezing the email field on narrow screens.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the footer's flex override so it renders through the standard 12-col
grid + per-block layout (mobile/tablet/desktop) like pages do. Add optional
column-start (desktopStart/tabletStart) to the layout system so blocks can be
offset in the grid — used to place the inline newsletter form directly under
the "Kontakt & Community" column.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add form-newsletter-inline internal component: compact email + button row
with a consent checkbox, dark-themed for the footer. Turnstile loads lazily
on first email focus (footer is on every page). Reuses /api/newsletter and
the newsletter validation. Wired into footer-main next to Kontakt & Community.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wire a newsletter signup form into the CMS internal-component pattern
(form-newsletter). Posts to /api/newsletter which subscribes to listmonk
(double opt-in) and mirrors a best-effort backup record to the RustyCMS
forms plugin. Reuses the contact-form anti-spam stack: Cloudflare
Turnstile, honeypots, client-age check, origin validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Punkt links der Datums-Kachel war der event-item <li>-Marker, nicht der
summary-Disclosure-Marker. list-none am <ul> wird von globaler Typo-Regel
überschrieben → list-style:none + ::marker{content:""} direkt auf .event-item.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
EventDateBox von Grund auf neu: <time> mit a11y-Label, feste rem-Schriften
statt fluid/calc-Skalierung, size-16/sm:size-20. Range-Box: gleiche Höhe,
nur breiter; symmetrisches gap → Monat rutscht nicht mehr aus der Box.
Zusätzlich iOS-Safari Disclosure-Marker (dunkler Punkt) in CalendarBlock
ausgeblendet.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Feste px-Schriftgrößen + h-20 verursachten auf Mobile Overflow ("Jun"
rutschte raus). Jetzt eine CSS-Var --s (Kantenlänge, responsive clamp);
alle Innenmaße per calc() abgeleitet. Range-Box nur breiter, gleiche
Höhe → identische Schrift wie Einzel-Box.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- app.css: erster Markdown-Absatz im Artikel auf --text-primary (schwarz)
statt --text-secondary (grau).
- Comments-Empty-State: kleineres helleres Icon (size-5/stein-300), Text
semibold + stein-300 (gleich hell wie Icon), engerer Icon-Text-Abstand.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Einzel- und Mehrtages-Datum in eine dedizierte Komponente ausgelagert.
Beide Varianten gleiche Höhe (h-20); Mehrtag zeigt Wochentag- und Tag-Range
(z. B. "Sa–So" / "27–28") und wächst nur in der Breite. Zentriert gestapelt
(kein Overflow), himmel-Box konsistent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
/termin/<slug> ist jetzt echte Seite statt Redirect:
- alle Infos ungekürzt (Datum/Zeit in Europe/Berlin, Ort+Maps, Tags,
Bild+Lightbox, volle Beschreibung, Anhang, externer Link)
- alle Aktionen: ICS, Google, Link kopieren, Teilen, QR, Social-Bild
- Link zum Kalender drunter (kein Auto-Redirect mehr)
- Breite via Layout-.container-custom (gleich wie andere Seiten)
- SEO: OG/Twitter/canonical zentral aus Layout (kein Doppel-Tag),
Event-JSON-LD + Breadcrumb für Rich Results / Share-Preview
CalendarBlock: QR-Button + "Details →"-Link je Termin (→ /termin/<slug>/).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Social-Image-Generierung lief SSR auf Server-TZ (UTC) → terminZeit
"10:00+02:00" wurde als "08:00" aufs Bild gerendert (−2h im Sommer).
toLocaleDate/TimeString in Kalender- und Post-Route auf timeZone
"Europe/Berlin" gepinnt. Cache-Version v26→v27 invalidiert alte PNGs.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- globalen Grid-Row-Trenner (::before aus app.css) im Flex-Footer abschalten
→ kein Phantom-Flex-Item mehr, Inhalt bündig links
- Trailing-Margins (letzter Block + letztes <p>) auf 0 → kein Leerraum unten
- Markdown-Links unterstreichen (konsistent mit den Link-Listen)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Kit-Bump auf 2.65 entfernte transitives @types/geojson aus dem Lockfile —
CI-tsc fand den globalen GeoJSON-Namespace nicht mehr. @types/geojson als
devDependency + explizite Type-Imports statt UMD-Namespace.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>