Commit Graph

298 Commits

Author SHA1 Message Date
Peter Meier fe7bce2935 style(radius): Modal-Panels rounded-lg, ContentModal-Button rounded-md
Deploy / verify (push) Successful in 1m34s
Deploy / deploy (push) Successful in 1m31s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 10:55:23 +02:00
Peter Meier 657f726edb refactor(consolidate): ArrowLink tone + FormSuccess-Komponente
Deploy / verify (push) Successful in 1m39s
Deploy / deploy (push) Successful in 1m34s
A: ArrowLink um tone-Prop (himmel/wald/stein/white) — PostOverview + CalendarCompact
inline Arrow-Links → ArrowLink.
B: 3× identische Formular-Success-Boxen → internal/FormSuccess.svelte (rounded-lg).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 10:53:43 +02:00
Peter Meier f77314dc49 feat(blocks): SectionGrid/InfoCard/ContactForm + Konsolidierung (Tier 1)
Deploy / verify (push) Successful in 1m31s
Deploy / deploy (push) Successful in 1m33s
Neue Komponenten: SectionGrid, InfoCard (tone/compact), ArrowLink, ContactFormBlock,
SectionGridBlock. CMS-Blöcke section_grid + contact_form (info_card-Collection).
OrganisationsBlock: presentation "grid" (SectionGrid + InfoCard-Tiles).
Kontaktformular-Submit: size md + Send-Icon.

Konsolidierung Tier 1:
- .card-surface + Card-Atom → rounded-lg, .chip → rounded-full, Input-Atome → rounded-md
- tote .btn-*-Klassen aus app.css entfernt (Atom nutzt --color-btn-*-Tokens)
- hardcoded Hex → stein-Tokens (InfoCard, ContactFormBlock)
- redundante rounded-sm auf card-surface-Nutzern entfernt

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 10:49:54 +02:00
Peter Meier 8fd0112dcb style(infocard): exakte Specs — Titel 16px/700, Deko-Farben, p-22 gap-14
Deploy / verify (push) Successful in 1m27s
Deploy / deploy (push) Successful in 1m37s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 09:42:39 +02:00
Peter Meier 3878a2ed26 feat(section-grid): InfoCard + SectionGrid als CMS-Block
Deploy / verify (push) Successful in 2m27s
Deploy / deploy (push) Successful in 1m49s
Neuer section_grid-Block (SectionHeader + Card-Grid aus info_card-Refs) +
info_card-Collection. SectionGrid/InfoCard-Komponenten, BlockRenderer-Case,
content_layout erlaubt section_grid in Rows. SectionHeader.title jetzt optional
(Kicker-only-Header).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 09:37:05 +02:00
Peter Meier 7c7538a22c refactor(badge): eine Badge-Komponente überall, alle 7 CMS-Farben
Deploy / verify (push) Successful in 1m36s
Deploy / deploy (push) Successful in 1m42s
components/Badge.svelte = einzige Badge-Quelle. colorClasses deckt jetzt alle
CMS-badge.color-Werte ab (green/blue/amber/orange/purple/teal/slate) — vorher
fielen orange/purple/teal/slate auf grau (Regionen-Badges sahen gleich aus).

Ad-hoc Badge-Spans (ContactCard, AdressbuchBlock) durch <Badge> ersetzt.
Verwaiste ui/Badge.svelte (0 Nutzungen) + Atoms/Badge-Story entfernt.
Molecules/Badge-Story zeigt jetzt alle Farben.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 09:26:48 +02:00
Peter Meier b60da59c92 feat(headline): optionaler SectionHeader-Modus (kicker/number/action)
Deploy / verify (push) Successful in 1m28s
Deploy / deploy (push) Successful in 1m36s
HeadlineBlock rendert als SectionHeader sobald kicker oder action gesetzt ist,
sonst schlichte Text-Headline wie bisher (rückwärtskompatibel, opt-in).
SectionHeader-Titel unterstützt jetzt \n → <br>. headline-Schema extends
section_header.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:48:23 +02:00
Peter Meier 03e84c1f28 feat(design-system): Storybook + Button-Atom-Vereinheitlichung + SectionHeader
Deploy / verify (push) Successful in 1m39s
Deploy / deploy (push) Successful in 2m9s
Storybook (SvelteKit-Framework, Tailwind v4, MSW, Translation-Decorator):
Stories für Atoms/Molecules/Organisms + alle CMS-Blocks.

Button-Atom: 5 .btn-*-Varianten (primary/secondary/tertiary/outline/warning),
class-Merge-Prop, href→<a>, Loading-Spinner neben Label, rounded-md/font-medium.
Alle rohen .btn-*- und Hand-Style-Buttons app-weit aufs Atom migriert.

SectionHeader-Molecule (kicker/number/title/subtitle/action) + Integration in
7 CMS-Blocks (post_overview, organisations, organisations_map, searchable_text,
image_gallery, youtube_video_gallery, files) via neuem section_header-Schema.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 23:35:57 +02:00
Peter Meier 289cdb3951 feat(home): Featured-Post-Layout, Termine-Look, Zitat-Sektion, Typo-Regelwerk
Deploy / verify (push) Successful in 1m31s
Deploy / deploy (push) Successful in 2m10s
- PostOverview: neues design "featured" (1 großer Post links, Rest kompakt
  rechts als PostCardCompact – Bild links, Text rechts, keine Nested-Links)
- CalendarCompact: Termine als Liste mit Datum-Badge + Kicker-Headline
- QuoteCarousel: dunkle Full-Bleed-Sektion, Lora-Zitat mit «», Author-Split,
  Kicker mit Sektionsnummer, Pill-Pagination + Pfeile/Swipe
- Typo-Regelwerk: Lora statt Aleo (Zitate), Headings semibold (600),
  H2/H3-Skala, "Weiterlesen"-Link-Muster, docs/typography.md
- HeadlineBlock: \n → <br> für bewusste Umbrüche
- Layout: neues spaceTop-Feld (mt-*), analog spaceBottom
- OrganisationsBlock: CTA volle Breite, Button rechts

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 16:40:05 +02:00
Peter Meier 91e66d8d4f fix(docker): healthcheck 127.0.0.1 statt localhost (IPv6 ::1 refused)
Deploy / verify (push) Successful in 1m10s
Deploy / deploy (push) Successful in 1m27s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 23:25:36 +02:00
Peter Meier 4376c40369 feat(stellungnahme): zentrales KI-Regelwerk aus stellungnahme_config
Deploy / verify (push) Successful in 1m21s
Deploy / deploy (push) Successful in 2m13s
Die AI-Rewrite-Regeln (DEFAULT_AI_RULES) waren im Block hardcodiert und
hätten pro Generator (40 Instanzen) dupliziert werden müssen, um im CMS
editierbar zu sein. Stattdessen ein Singleton stellungnahme_config
(Slug "default") mit Feld aiRules: der Resolver lädt es einmal und hängt
block.aiRules an alle Generator-Blöcke. Komponente seedet daraus, mit
DEFAULT_AI_RULES als Code-Fallback; Reset-Button setzt auf den CMS-Wert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 13:56:16 +02:00
Peter Meier 7379d5750c fix(youtube-gallery): remove crossfade flash on carousel navigation
Deploy / verify (push) Successful in 1m23s
Deploy / deploy (push) Successful in 1m45s
The carousel iframe row was wrapped in {#key currentIndex} with
transition:fade, so switching slides (or navigating to the page) faded
the old and new row in overlap — briefly showing two rows / a blink.
Drop the fade from both iframe containers, matching the modal variant
which uses {#key} without a transition.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 22:48:10 +02:00
Peter Meier 84c41f80b1 feat(modal): route-targeted content modals on navigation
Deploy / verify (push) Successful in 1m12s
Deploy / deploy (push) Successful in 2m10s
Add a global modal/popup system driven entirely from the CMS. A new
`modal` config collection self-targets routes via a glob/regex urlPattern
(optional time window), and its `content` array of block references renders
through the existing BlockRenderer — so markdown, HTML and YouTube blocks
work exactly like a page row. A `modals` list collection holds the active
set behind an enable flag (analogous to `campaigns`).

- modal-match.ts: glob (`*`/`**`) + `~regex` pathname matcher, time window
  and modal selection helpers (+ unit tests)
- ContentModal.svelte: immediate/delay/scroll/exit_intent triggers, session
  vs. permanent dismiss (sessionStorage + localStorage, keyed by slug+version)
- +layout.server.ts: load `modals-global` in the bootstrap batch, resolve
  block images server-side
- +layout.svelte: mount on non-embed routes, match against the current path

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 09:47:49 +02:00
Peter Meier 121b593e4e Blog: Abstand unter Pagination/Sortier-Zeile (mobile)
Deploy / verify (push) Successful in 1m8s
Deploy / deploy (push) Successful in 1m34s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 10:42:22 +02:00
Peter Meier e96bfee317 Blog-Übersicht: Featured-Hero, Neu-Badge, Org-Sektion, Sortierung, konsolidiertes Suchfeld
Deploy / verify (push) Successful in 1m18s
Deploy / deploy (push) Successful in 1m31s
- SearchField-Atom (src/lib/ui/SearchField.svelte, light/dark) in Kalender,
  Beiträge und globaler Suche einheitlich eingesetzt
- Featured-Hero (neuester Beitrag groß, Seite 1 ungefiltert, nur bei "newest")
- Neu-Badge in PostCard (Beitrag < 7 Tage)
- Org-/BI-Tags (tag-org-*) in eigene Sektion; Tags ohne Beiträge ausgeblendet
- Inline-Newsletter-CTA, prominenter RSS-Link
- Sortierung Neueste/Älteste (Server-Param + URL-State, Toggle neben Pagination,
  Pagination trägt sort weiter)
- Pagination als Pills (rounded-full)
- Kalender: Tag-Filter einklappbar, Filterleiste mit Suche + Heute

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 10:40:07 +02:00
Peter Meier f86c302d49 feat(stellungnahme): UX-Politur Ausgabe + Betroffenheit
Deploy / verify (push) Successful in 1m7s
Deploy / deploy (push) Successful in 1m34s
- Output-Hierarchie: Schreibvorlage 'Empfohlen', KI-Block 'Optional'
- KI-Block: 4-Schritte-Anleitung eingeklappt (weniger dicht)
- Betroffenheit: konkrete Beispiel-Liste + Zeichenzaehler

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:24:07 +02:00
Peter Meier c60412bb53 style(windkarte): Hinweis-Icon (mouse-pointer-click) statt Emoji
Deploy / verify (push) Successful in 1m9s
Deploy / deploy (push) Successful in 1m35s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:03:37 +02:00
Peter Meier f8bbf59f90 style(windkarte): Hinweis kleiner (text-xs), Bindestrich raus
Deploy / verify (push) Successful in 1m16s
Deploy / deploy (push) Successful in 1m28s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 16:02:25 +02:00
Peter Meier c12d626507 feat(pwa): installierbar + Offline-Grundgeruest
Deploy / verify (push) Successful in 1m7s
Deploy / deploy (push) Successful in 1m45s
- Manifest (name/standalone/theme-color wald), Icons aus echtem Logo
  (192/512/maskable/apple-touch) via scripts/generate-pwa-icons.mjs
- app.html: manifest + theme-color + apple-touch-icon + iOS-Meta
- service-worker.ts: precache Build-Assets, Seiten network-first mit
  Offline-Cache-Fallback (SvelteKit registriert autom. in Prod)
- Push (VAPID) folgt separat

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:58:35 +02:00
Peter Meier e5566ff797 feat(regionalplan): Generatoren leichter finden
Deploy / verify (push) Successful in 1m12s
Deploy / deploy (push) Successful in 1m32s
- 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>
2026-07-01 15:47:48 +02:00
Peter Meier 7a490b1ae1 feat(frist): Deadline-Banner im AnnouncementBanner-Look (rot), nur ein Balken
Deploy / verify (push) Successful in 1m11s
Deploy / deploy (push) Successful in 1m29s
- Look wie AnnouncementBanner: kompakte zentrierte Leiste, weiße Schrift, 0.7rem,
  variant-Farbe (urgent=rot), flex-wrap → fließt/stackt sauber mobil
- Countdown als dunkles Badge (bg-black/20)
- Layout: aktive Frist verdrängt NEU-Banner → nie 2 Balken über der Navi

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:32:40 +02:00
Peter Meier f7529d3b47 feat(frist): Deadline-Countdown site-weit + variant-Styling (urgent=rot)
- DeadlineBannerBlock: Farbe nach variant (urgent rot / accent / info / default)
- Layout: deadline-banner-auslegung-2026 site-weit im Bootstrap geladen + oben
  gerendert (vorher nur auf /regionalplan)
- page-regionalplan: inline-Banner entfernt (kein Doppel), Content folgt separat

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:19:38 +02:00
Peter Meier 3908c117df style(header mobile): Menü-Button farbiger hinterlegt (wald-600/25)
Deploy / verify (push) Successful in 1m12s
Deploy / deploy (push) Successful in 1m27s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 15:06:16 +02:00
Peter Meier 5591bd86f0 feat(post): Vorlesen-Button (Web Speech API), nur wenn unterstützt
Deploy / verify (push) Successful in 1m17s
Deploy / deploy (push) Successful in 1m39s
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>
2026-07-01 09:54:12 +02:00
Peter Meier 85d6314ab4 style(header mobile): Menü kompakter + Such-Overlay an Menü-Look angeglichen
Deploy / verify (push) Successful in 1m18s
Deploy / deploy (push) Successful in 1m42s
- Menü: Hauptpunkte text-sm + py-2.5 (kein Größensprung zu Subpunkten),
  Active nur per Farbe (kein font-bold), CTA-Buttons Ghost + Icons
- Search.svelte: dunkel-frosted Overlay (bg-stein-900/90 + blur), absolute
  statt in-flow, dunkler Input, helle Ergebnisse — konsistent mit dem Menü

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 16:04:50 +02:00
Peter Meier 7f67f59c8c style(header mobile): mehr Bottom-Platz im Menü, CTA-Buttons rounded-full
Deploy / verify (push) Successful in 1m7s
Deploy / deploy (push) Successful in 1m24s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 15:55:54 +02:00
Peter Meier 25c1c5f2ed feat(header mobile): Pills wie Desktop, Menü-Overlay optimiert
Deploy / verify (push) Successful in 1m8s
Deploy / deploy (push) Successful in 1m27s
- Suche + Menü als Desktop-Pills (rounded-full, wald-700/8), Icons text-sm,
  Menü mit Label „Menü/Schließen"
- Menü-Overlay: absolute (überlagert statt schiebt), bg-stein-900/90 +
  backdrop-blur-lg, scrollbar (max-h dvh, overscroll-contain, Safe-Area-pb)
- CTA-Block oben: Mitmachen + Termin melden (btn-sm)
- aktive Sektion auto-aufgeklappt, Submenu-Targets py-3
- Logo mobil h-8 (Desktop h-10)
- Header backdrop-blur-md entfernt (entsperrt Kind-backdrop-filter)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 15:49:59 +02:00
Peter Meier 9115134852 fix(header): mobiles Menü — Safe-Area-Bottom-Padding (iOS letzter Punkt verdeckt)
Deploy / verify (push) Successful in 1m12s
Deploy / deploy (push) Successful in 1m39s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 15:29:35 +02:00
Peter Meier fe8afdb08e fix(header): mobiles Menü scrollbar (Overlay-Scroll-Container)
Deploy / verify (push) Successful in 1m16s
Deploy / deploy (push) Successful in 1m47s
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>
2026-06-30 15:24:21 +02:00
Peter Meier 4d45f56719 refactor(ui): btn-warning Button-Variante + gelb-Token statt inline-style
Deploy / verify (push) Successful in 1m18s
Deploy / deploy (push) Successful in 1m33s
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>
2026-06-29 12:47:44 +02:00
Peter Meier 2c61cc03b2 style(kalender): Termin-melden-Button Gelb als inline-style
Deploy / verify (push) Successful in 1m10s
Deploy / deploy (push) Successful in 1m47s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 12:44:53 +02:00
Peter Meier 514e4425b5 style(kalender): Termin-melden-Button gelb hinterlegt
Deploy / verify (push) Successful in 1m15s
Deploy / deploy (push) Successful in 1m56s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 12:44:14 +02:00
Peter Meier 4f408ee204 feat(termine): „Termin melden"-Link in Kalender + Footer-Sitemap
Deploy / verify (push) Successful in 1m20s
Deploy / deploy (push) Successful in 1m39s
CalendarBlock: Termin-melden-Button in Action-Zeile.
Footer-Sitemap: link-termin-melden (CMS) → /termin-melden.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 12:03:31 +02:00
Peter Meier 8c537a0ae7 feat(stellungnahme): KI-Regeln — Quellen konkret nennen, keine Anlagen-Verweise
Deploy / verify (push) Successful in 1m34s
Deploy / deploy (push) Successful in 1m53s
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>
2026-06-29 10:37:19 +02:00
Peter Meier ca4dfad8be feat(termine+matrix): Nutzer-Termin-Einreichung (Draft) + Matrix-Notifications
Deploy / verify (push) Successful in 1m32s
Deploy / deploy (push) Successful in 1m54s
- /termin-melden: öffentliches Formular → /api/termin legt calendar_item als
  Draft an (scoped Write-Key), Admin bestätigt per draft→published
- /api/cms-webhook: empfängt RustyCMS-Webhooks (X-Webhook-Secret) → Matrix
- src/lib/server/matrix.ts: notifyMatrix() Helper
- Form-Proxies (stellungnahme/contact/newsletter/mitmachen) pingen Matrix
- deploy.yml: Matrix/Webhook/Termin-Key Env-Vars

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 10:32:36 +02:00
Peter Meier 5b5fe8789e feat(stellungnahme): Send-Panel — tägliche Bearbeitung + E-Mail-Versand-Hinweis
Deploy / verify (push) Successful in 1m19s
Deploy / deploy (push) Successful in 1m34s
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>
2026-06-28 20:43:03 +02:00
Peter Meier cb66442aac fix(stellungnahme): Sende-Status bei Neu-Erzeugen zurücksetzen
Deploy / verify (push) Successful in 1m33s
Deploy / deploy (push) Successful in 1m43s
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>
2026-06-28 12:21:31 +02:00
Peter Meier 7788e0370e feat(link-list): CMS-Feld columns (auto|single) für Spaltenlayout
Deploy / verify (push) Successful in 1m13s
Deploy / deploy (push) Successful in 1m28s
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>
2026-06-26 22:40:30 +02:00
Peter Meier 552446b670 feat(stellungnahme): "An das Team senden" — Prompt landet in RustyCMS
Deploy / verify (push) Successful in 1m16s
Deploy / deploy (push) Successful in 1m37s
- StellingnahmeGeneratorBlock: Senden-Panel im KI-Block (Name, Email,
  Vorranggebiet, generierter Prompt) → /api/stellungnahme, Consent + Honeypot
- neuer Endpoint /api/stellungnahme spiegelt /api/contact (Origin, Honeypot,
  client-age, Validierung) → forwarded an CMS forms-Plugin
- Privacy-Notice: Senden = ausdrückliche Übermittlung

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 22:31:39 +02:00
Peter Meier d64754c238 feat(search): Multi-Wort + Ranking + Keyboard-Nav; fix LinkList-Spalten
Deploy / verify (push) Successful in 1m18s
Deploy / deploy (push) Successful in 1m33s
- Search: AND-Match über Tokens, Feld-gewichtetes Ranking, ↑↓⏎-Nav,
  Match-Highlight, Trefferzahl + aria-live
- LinkListBlock: breitenbasierte Spalten (auto-fill minmax) statt fixer
  4-Zeilen-Grid — verhinderte Zerbröseln bei vielen langen Labels

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 21:44:34 +02:00
Peter Meier 52929122f5 fix(ui): roter NEU-Badge, separate Nav-Pills, Footer-Headlines + Spalten
Deploy / verify (push) Successful in 1m26s
Deploy / deploy (push) Successful in 1m44s
- 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>
2026-06-26 12:20:24 +02:00
Peter Meier 81c067fa0c fix(newsletter): stack inline footer form on mobile
Deploy / verify (push) Successful in 1m14s
Deploy / deploy (push) Successful in 1m30s
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>
2026-06-25 13:38:57 +02:00
Peter Meier d8a6508cde feat(footer): use the grid layout system instead of fixed flex columns
Deploy / verify (push) Successful in 1m18s
Deploy / deploy (push) Successful in 1m28s
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>
2026-06-25 13:19:59 +02:00
Peter Meier 686af53be0 feat(newsletter): slim inline newsletter form for footer
Deploy / verify (push) Successful in 1m12s
Deploy / deploy (push) Successful in 1m54s
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>
2026-06-25 13:08:27 +02:00
Peter Meier af90483dc4 feat(newsletter): newsletter signup as internal component
Deploy / verify (push) Successful in 1m18s
Deploy / deploy (push) Successful in 1m34s
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>
2026-06-25 11:02:48 +02:00
Peter Meier 0ab2c58eb4 feat(header): icon nav redesign + migrate icons mdi→lucide
Deploy / verify (push) Successful in 1m26s
Deploy / deploy (push) Successful in 2m26s
- 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>
2026-06-24 10:44:56 +02:00
Peter Meier e434ee3620 feat(termin): Termin-Detail unter /kalender/termin/<slug>, 302 von alt
Deploy / verify (push) Successful in 1m21s
Deploy / deploy (push) Successful in 1m39s
Route /termin/[slug] -> /kalender/termin/[slug] verschoben, alte URL
302-redirect (QR-Codes/geteilte Links bleiben gueltig). Breadcrumb 3-stufig
(Start > Kalender > Titel). QR-/Detail-/OG-Links auf neuen Pfad.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 10:35:15 +02:00
Peter Meier a628e0e8d1 fix(calendar): <li>-Disc-Marker (Punkt) auf iOS/WebKit entfernen
Deploy / verify (push) Successful in 1m12s
Deploy / deploy (push) Successful in 1m34s
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>
2026-06-22 23:18:56 +02:00
Peter Meier a0e2015eeb fix(calendar): EventDateBox simpler flex-center Layout (Safari-fest)
Deploy / verify (push) Successful in 1m17s
Deploy / deploy (push) Successful in 1m30s
Grid/calc/leading-Experimente raus. Schlichtes flex justify/items-center
mit innerem text-center-Block (Wochentag/Tag/Monat) — rendert auf iOS
Safari zuverlässig. wald-Farbschema + rounded-br-4xl + shadow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 23:11:10 +02:00
Peter Meier d484a7d90b fix(calendar): leading-none auf Tag-Zahl — Tailwind text-* default line-height blähte Zeilenbox, JUN an Unterkante
Deploy / verify (push) Successful in 1m11s
Deploy / deploy (push) Successful in 1m30s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 22:18:26 +02:00