Commit Graph

111 Commits

Author SHA1 Message Date
fs
1c4f5cdbc5 Instagram-Sync reparieren: feed/user-Endpunkt als Strategie 1
web_profile_info antwortet seit kurzem mit HTTP 400 und einem
Instagram-internen Schema-Fehler ("Asset asset://laser.provider/
ig_business_category_subvertical has been deleted") — kein IP-Block.
Gleichzeitig enthält das Profil-HTML kein edge_owner_to_timeline_media
mehr, womit auch der zweite Fallback tot war und der Cache seit
20.06. nicht mehr aktualisiert wurde.

api/v1/feed/user/{username}/username/ liefert weiterhin 200 mit den
letzten Posts, nur in anderer Form (items[] mit image_versions2 statt
edges[] mit display_url). Neuer Extractor dafür, eingehängt als
Strategie 1; die bisherigen zwei bleiben als Fallback 2 und 3.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 23:30:11 +02:00
fs
819bdf6173 SEO/GEO-Basics: Descriptions & Titles normalisiert, Outline-Fixes, CLS-Maße
Audit aller 23 indexierbaren Routen (lokaler Crawl) und Fixes:
- Descriptions auf ~130-160 Zeichen; Turnen-Disziplinseiten hatten den
  kurzen Hero-Teaser als Description, jetzt eigene SERP-Texte
- Titles: team-erste gekürzt, sportheimbuchung ohne doppelten Brand
- h1->h3-Sprünge behoben: visually-hidden h2 aus JSON-Section-Titeln
  (sportheimbuchung, partner-werden), sichtbarer choice.title auf
  mitglied-werden; historie bekommt Breadcrumb-Schema
- Neuer Helper img_intrinsic_attrs() liefert width/height aus der
  Bilddatei (PNG via getimagesize, SVG via viewBox) für Partner-Grid-
  und Banner-Slider-Logos — kein Layout-Shift mehr

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 00:27:19 +02:00
fs
3d8ded28da Mailversand: Brevo durch All-Inkl-SMTP ersetzt + sendefreier Verbindungstest
Versand läuft jetzt über das KAS-Postfach noreply@tsv08kulmbach.de
(w01ca75d.kasserver.com:587, STARTTLS) — ein Drittanbieter weniger,
SPF der Domain deckt den Server bereits ab. bin/smtp-test.php prüft
Verbindung, TLS und Login ohne eine Mail zu versenden (Debug bewusst
aus, damit keine Credentials im Terminal landen).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 00:27:19 +02:00
fs
3a591fe8d0 Matchcenter: Saison-Tabs, Vorsaison-Archiv & gehärteter Cache-Write
- Sync schreibt Cache jetzt fehlersicher: json_encode mit JSON_THROW_ON_ERROR
  + Rückgabeprüfung von file_put_contents/rename → ein defektes UTF-8-Zeichen
  aus der BFV-API kann den guten Cache nicht mehr leerschreiben (alter Cache
  bleibt via $fail unangetastet)
- Vorsaison wird bei erkanntem compoundId-Wechsel einmalig archiviert (previous),
  pro Team compound_id + abgeleitetes season-Label + stale-Flag persistiert
- Aktuelle Saison ist immer sichtbar (auch leer), Wechsel zur Vorsaison über
  wiederverwendete Stripe-Tabbar (group-tabs); neue Komponente matchcenter-season
- Leere aktuelle Saison zeigt Hinweis statt leerer Fläche

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 00:51:14 +02:00
fs
9722d8eccc SEO/GEO-Feinschliff: og:image:alt, areaServed, WebSite-Knoten, Team-Descriptions
- og:image:alt (Seitentitel) in meta.php — Social-/AI-Cards + A11y
- areaServed (Kulmbach + Landkreis Kulmbach) am SportsClub-JSON-LD-Knoten
- WebSite-Knoten auf der Startseite via neuem Helper website_schema(), publisher -> #club
- Explizite, Kulmbach-haltige Team-Descriptions (<=155 Zeichen) statt roher Hero-Texte
  (zweite-mannschaft war 214 Zeichen und wurde im Snippet abgeschnitten)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 23:17:53 +02:00
fs
8437f00e06 Feinschliff: Formulare neu, Glas global dunkler, Hero-Fade sauber
Formulare (form-field.php, 3 Form-Wrapper, components.css, form.js):
- Floating Labels (Label im Feld, wandert bei Fokus/Inhalt hoch; select/date
  dauerhaft oben) via :has() + placeholder=" "-Trick. Echtes <label> bleibt
  im DOM (kein Placeholder-als-Label).
- Globale "Pflichtfelder mit *"-Hinweiszeile entfernt; Stern bleibt am Feld,
  pro Feld als visually-hidden "(Pflichtfeld)" für Screenreader erklärt.
- Markenroter Fokus-Ring statt Weiß.
- Felder als sanfter Füll-Look: weichere Ränder (eigene --clr-field-*-Tokens),
  Erkennbarkeit über Fläche + Rand (WCAG 1.4.11 erfüllt).
- form.js: Submit-Button-Text wird je Formular korrekt wiederhergestellt.

Glas-Look global (tokens.css, components.css):
- Frosted Glass zentral: --glass-blur + --glass-shadow (Glow + Top-Sheen),
  eine Regel statt 28× wiederholt; Leaf-Karten mit Blur, Container nur Glow
  (kein Doppel-Frost). @supports-Fallback.
- Dunkleres Glas (--clr-glass-bg auf Schwarz-Tint), dezenter Card-Rand.

Hero-Fade (components.css):
- Unterer Auslauf nicht mehr mit grauem --clr-bg zugedeckt, sondern .hero__media
  per mask-image ausgeblendet → echter dunkler, texturierter Hintergrund scheint
  durch (schwärzer, durchsichtig, kein graues Band). Abdunklung auf reines
  Schwarz. Gilt für alle drei Hero-Varianten.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 22:18:34 +02:00
fs
08f5a1ae9b Kontaktseite: eigene /kontakt mit Hero + Formular
Neue /kontakt-Seite (Hero + wiederverwendete contact-form-Komponente, ohne
Intro-Block). Behebt die bisher ins 404 laufenden "Kontakt aufnehmen"-CTAs.

- contact-form: optionales $intro + Rücksprung-Slug $return (Hidden-Feld)
- contact-submit: PRG-Redirect zur absendenden Seite, whitelist-validiert
  gegen routes.php (kein Open-Redirect)
- Verlinkt im Footer-Rechtsbereich und im Menü "Der Verein"

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 21:14:28 +02:00
fs
23778324c7 Nav-Dropdown: Panel-Padding wirkt jetzt + gleichmäßiger Innenabstand
Das Submenu-Padding wurde stillschweigend vom globalen reset.css-Selektor
`ul[class] { padding: 0 }` (Spezifität 0,1,1) überschrieben, da
`.site-nav__submenu` nur (0,1,0) hat — die Hover-/Active-Pillen klebten
dadurch links/rechts am Panel-Rand. Selektoren auf
`.site-nav__list .site-nav__submenu` (0,2,0) gehoben (Haupt-Regel,
@supports-Glas, Mobile-Override), sodass das Padding ohne !important greift.
Innenabstand auf gleichmäßige 0.55rem rundum gesetzt — Pillen stehen
oben/unten/seitlich gleich dezent frei.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 21:08:59 +02:00
fs
adf142b18e Feinschliff: Navigation, Hero-Center, Personen-Karten & Tokens
Querschnitt-Verbesserungen ohne eigenes Feature:
- Navigation: Untermenü-Trenner (separator) + Mitmachen-Link, rote Akzent-Leiste
- Startseiten-Hero zentriert (align center, ohne Hero-CTAs); .hero--center-Styles
- person-card/person-grid: Kontakt-Layout, 3-Spalten-Raster (Startseite)
- jsonld: geo aus club.json; cta unterstützt #hash-Anker
- verein: hartcodierten Maps-Link/Inline-CTA entfernt, .facility zentriert
- tokens: Sepia-Farben für Timeline; base: globale p-max-width entfernt
- historie: Timeline um 2024/2025 ergänzt
- Icons link-45deg (Footer) und robot (meta) nachgereicht

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 20:49:46 +02:00
fs
a3d64e7d91 Banner-Slider: Vor-/Zurück-Steuerung
Prev/Next-Navigationsbuttons für den Banner-Slider (carousel.js, generisch über
[data-carousel-prev/next]), zugehörige ad-banner-Steuerungs-Styles und Chevron-
Icons. Ohne JS bleiben die Controls ausgeblendet (progressive enhancement).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 20:49:12 +02:00
fs
b40f36aee6 Turnen: Tab-Navigation für Gruppen mit vielen Trainingszeiten
group-schedule um eine Tab-Leiste (group-tabs) erweitert: bei Disziplinen mit
vielen Gruppen (z. B. Eltern-Kind-Turnen) werden die Gruppen als Tabs gruppiert
statt endlos gestapelt. JS (group-tabs.js) als progressive enhancement — ohne JS
bleiben alle Panels sichtbar. Begleitend Feinschliff an group-card/-list/schedule-row.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 20:48:39 +02:00
fs
1552f974aa Partner werden: Sponsoring-Argumente & Werbekanäle
Überarbeitete Seite /partner-werden mit Argument-Karten (sponsor-arguments)
und einer Übersicht der Werbekanäle (sponsor-channels) aus
data/partner-werden.json, inkl. zugehöriger Icons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 20:47:30 +02:00
fs
2c0594811c Mitmachen: Ehrenamtsseite mit Stellen-Filter
Neue Seite /mitmachen, die offene Ehrenamtsstellen aus data/mitmachen.json als
position-card-Komponente listet, mit clientseitigem Bereichsfilter
(position-filter.js, progressive enhancement) und JobPosting-Schema
(job_posting_schema(), employmentType VOLUNTEER). Route ergänzt.
Enthält zudem kleine person-card__contact-Stilanpassungen (gleiche CSS-Sektion).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 20:47:13 +02:00
fs
6a612e52c3 Sportheim mieten: Buchungsseite mit Anfrageformular
Neue Seite /sportheimbuchung mit Bento-Layout (Fotos, Lage, Ausstattung) und
einem Buchungsanfrage-Formular nach Projektkonvention (form-field-Komponente,
Status-Region, Honeypot + ft-Token, Whitelist-Validierung, Rate-Limiting, PRG).
Versand via Brevo SMTP über app/actions/sportheimbuchung-senden.php, POST-Route
in index.php. form-field um min/max-Attribute erweitert (Personenzahl-Feld).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 20:46:44 +02:00
fs
e7801ca6ee Spam-Schutz: Rate-Limiting, Link-Heuristik & Spam-Logging
Mehrschichtiger Formular-Schutz ohne externe Dienste, ergänzend zu Honeypot
und HMAC-Time-Trap:
- rate_limit_ok(): pro IP+Route (5/10 min), Tages-Cap (100/Tag), Token-Replay
- client_ip() / log_spam() (abgewiesene Versuche -> storage/logs/spam.log)
- Honeypot-Feld website -> company_url umbenannt (contact-/membership-form)
- Ratelimit-Hinweis in form.js
- storage/ratelimit/ (gitignored bis auf .gitkeep)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 20:41:50 +02:00
fs
73583a896c CLAUDE.md mit Code-Stand abgeglichen + Hero-Regel dokumentiert
- Hero-Regel festgeschrieben (Startseite groß, Unterseiten Überschrift +
  Teaser); gleiche Konvention im Docblock von hero.php
- Single-Source-Tabelle generalisiert (Seiteninhalte -> data/<slug>.json)
  + ansprechpartner.json als geteilte Personen-Quelle
- Spam-Schutz vollständig: Rate-Limiting, Link-Check, spam.log
- JSON-LD-Helper (sportsevent_nodes, job_posting_schema) und Helper-Liste
  (abs_url, config, form_token) ergänzt
- bin/img-resize.php und vollständige Logs-Liste dokumentiert

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 20:30:04 +02:00
fs
169878a4f7 Heros vereinheitlicht: Unterseiten nur Überschrift + Teaser
Alle Unterseiten-Heros auf ein einheitliches Muster gebracht — nur title +
text, dazu compact und align bottom-left. kicker und tagline entfernt
(team-erste/zwei/damen, jugendfussball, matchcenter, ansprechpartner,
mitglied-werden), historie von zentriert auf bottom-left. Der große
Startseiten-Hero (display) bleibt unverändert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HGzc6GhWhmLJt1jC2q1SRZ
2026-06-20 20:29:57 +02:00
fs
4b78285698 Neue Seiten: Mitglied/Partner werden, Sportheimbuchung & Ansprechpartner
Mitglied werden: Hub-Seite mit Online-Anmeldung (membership-form +
membership-submit-Action, Honeypot + Time-Trap), Abteilungswahl
(department-choice), Beitragstabelle (fee-table) und Turn-Aufnahmeantrag
als PDF-Download. Daten in data/mitglied-werden.json.

Partner werden & Sportheimbuchung: neue Seiten samt Routing und Navigation.

Ansprechpartner: echter Hero (Vereinsgelände), Bereiche aus dem group-Feld
der Single Source (Fußball / Turnen) zu zwei Sektionen gebündelt, Disziplin
als Karten-Überschrift. Fehlende Turn-Disziplin-Leads (Frisque, Lorz,
Kornatz, Trotzke) aus den Turnen-Unterseiten extrahiert und in
data/ansprechpartner.json ergänzt (allgemeine Turnabteilungs-Mail als
Kontakt). WhatsApp für alle Personen mit Telefonnummer. person-grid:
kompaktere Karten, Hairline unter der Bereichsüberschrift, 5 Spalten am
Desktop. Startseite auf die Haupt-Ansprechpartner je Bereich begrenzt.

Dazu: neue Icons (check-circle, download, file-earmark-text, whatsapp),
Anpassungen an Header/Footer/CTA/age-groups sowie tokens/layout/utilities.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RZsKTL5kRSG4KkK8w2LKkE
2026-06-19 11:16:10 +02:00
fs
185365dc79 Matchcenter: Spielplan, Ergebnisse & Tabellen (eigene Seite statt BFV-Widget)
Neue Unterseite /matchcenter ersetzt die alten BFV-Widget-Embeds (verstoßen
gegen CSP) durch eine self-hostete Lösung: Cron-Scraper holt die Daten aus der
öffentlichen BFV-Widget-JSON-API, schreibt data/matchcenter.json und lädt die
Vereinswappen lokal — Besucher kontaktieren nur unsere Domain.

- bin/matchcenter-sync.php: CLI/Cron-Scraper (Muster wie instagram-sync), JSON-API
  team/{id}/matches + competition/{compoundId}/table, Wappen via getLogo lokal,
  atomarer Write, Fail-safe. Auto-Saison: Tabellen-compoundId wird aus der
  Matches-API abgeleitet (team_id ist saison-stabil). Per-Team-Cache-Fallback bei
  Fetch-Fehlern, damit Sektionen nie leeren.
- Seite app/pages/matchcenter.php + Route + Nav-Eintrag (unter Fußball).
- Komponenten: match-slider (nächste Spiele), match-card, match-row, league-table
  (mit Auf-/Abstiegszonen), matchcenter-section (kicker-Layout: Tabelle 2/3 +
  Spiele 1/3), matchcenter-empty, crest (weißes Chip + Initialen-Fallback).
- carousel.js: banner.js zum generischen [data-carousel]-Antrieb verallgemeinert
  (Banner- und Match-Slider teilen ihn); crest.js: Logo-Fallback im Browser.
- helpers.php: sportsevent_nodes() für SportsEvent-JSON-LD.
- Icons calendar-event; config.example + .gitignore + CLAUDE.md ergänzt.
- Responsive geprüft (kein Seiten-Overflow 360–1280, Tabelle scrollt in der Karte).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0192vTfGmGpoWeyUse4TuQFj
2026-06-19 10:57:14 +02:00
fs
ea622244db Turnabteilung: Übersicht + 5 Disziplin-Unterseiten im Bento-Layout
- Neue Übersichtsseite (Hub: Hero + Disziplin-Kacheln) sowie Unterseiten für
  Erwachsenenturnen, Eltern-Kind-/Kinderturnen, Step Aerobic/Fitness/Pilates,
  Trampolin und Wettkampfturnen. Inhalte 1:1 von der alten Seite, gepflegt in
  der neuen Single-Source data/turnen.json.
- Neue Komponente group-schedule im einheitlichen Bento-Look wie die
  Mannschaftsseiten: Dashboard mit Trainingszeiten, Kontakt-Kachel (mailto an die
  Turnabteilung) und Trainingsort; gestapelte/gerasterte Gruppen-Karten für
  Mehr-Gruppen-Disziplinen, rote Hinweis-Kachel (z. B. Warteliste).
- Routing (app/routes.php) und Navigations-Dropdown (data/navigation.json) für
  Turnen; zugehörige Styles in components.css.
- Themenbezogene, self-hostete Unsplash-Platzhalterbilder für die Kacheln.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 10:33:03 +02:00
fs
d0ff8922f3 Banner-Slider: ungenutzte Platzhalter-SVGs entfernt
placeholder-1/2/3.svg + bg-sample.svg wurden seit den echten Slides
(Eigenwerbung + Breadcrumb) von keiner Banner-Konfiguration mehr referenziert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:53:10 +02:00
fs
d82acc7f9c Banner-Slider: einspaltiges Layout, Logo oben links, Foto frei
Logo führt die Slide oben links an (statt großer Logo-Platte rechts); Inhalt
einspaltig, „Anzeige"/Status-Label als Pille unten rechts in der Fußzeile.
Damit gibt die rechte Hälfte das Hintergrundfoto frei — Motivwahl wird viel
einfacher. Logo nur rendern, wenn vorhanden; Wappen (Eigenwerbung) etwas größer.

Breadcrumb-Slide auf einen CTA reduziert: „Neue Website entdecken" → Startseite.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:52:21 +02:00
fs
d0d78d7a5c Banner-Slider: 1px-Durchschimmern an der Foto-Kante beheben
background-clip: padding-box auf den Foto-Varianten (--bg und house+bg),
damit das Hintergrundbild nicht unter den 1px-Rahmen (border-color:
transparent) gemalt wird und an der Kante durchschimmert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:45:14 +02:00
fs
ede0258cd8 Banner-Slider: Crossfade-Übergang + per-Slide-Akzentfarbe
Folienwechsel als sauberes Crossfade (best practice): Slides im selben
Grid-Feld gestapelt → konstante Höhe ohne Sprung, ein-/ausgehende Folie
blendet über (Opacity + leichtes translateY). JS steuert die Sichtbarkeit
über .is-active statt hidden; ohne JS bleibt der hidden-Fallback (erste Folie).
Reduced-Motion über den globalen Kill-Switch instant.

Neue Slide-Prop "accent" (CSS-Farbe) überschreibt das Vereins-Rot der Buttons
pro Slide; Breadcrumb-Slide nutzt #6cbbbc. Button-Text wird aus der Akzentfarbe
dunkel abgeleitet (color-mix), da helle Akzente mit Weiß zu wenig Kontrast haben.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:40:35 +02:00
fs
f294f1a9de Banner-Slider: Beispiel-Anzeige Breadcrumb Solutions
Zweite Slide als echte Sponsoren-Anzeige (Hero-Foto + Wortmarken-Logo,
self-hosted). Komponente erweitert um cta_secondary (Outline-Button) und
logo_light (weiße Logo-Platte für dunkle Firmenlogos). CTAs verlinken extern
(target=_blank, rel=sponsored) auf Lösungen + Über uns. Mit zwei Slides
aktiviert der Slider Auto-Rotation und Indikatoren.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:34:39 +02:00
fs
88fceb67b1 Banner-Slider: Eigenwerbung-Slide "Hier könnte Ihre Werbung stehen"
House-Ad mit TSV-08-Wappen und echtem Foto (fussball-hero) statt der
Platzhalter-Slides: wirbt selbst für die Werbefläche, CTA führt intern aufs
Kontaktformular (#kontakt). Komponente um generische Props erweitert: variant
(CSS-Modifier), tag (Badge-Text) und cta.internal (interner Link ohne
target=_blank/rel=sponsored). Neue Styles: rote Glas-/Foto-Variante mit
gestricheltem "Werbeplatz frei"-Frame, rot-dunkler Verlauf für Lesbarkeit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:27:57 +02:00
fs
02da2bd7b6 CLAUDE.md: SSoT-Tabelle um neue Datenquellen + JSON-LD-Konvention
SSoT-Tabelle ergänzt um teams/fussball/jugend/verein/banners.json, damit
Mannschafts- und Seiteninhalte aus der Quelle statt aus Templates kommen.
Per-Page-Meta-Abschnitt dokumentiert das $meta['schema']-Muster und die
*_schema()-Helper.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:16:35 +02:00
fs
c5f7b258ff Navigation: Dropdown-Untermenüs für Fußball und Verein
navigation.json gruppiert Fußball (Übersicht, Mannschaften, Jugend) und
Verein (Übersicht, Historie) als children. nav.php rendert Disclosure-Buttons
mit aria-expanded/-controls; ohne JS per CSS :hover/:focus-within bedienbar.
nav.js ergänzt Toggle, Escape (Untermenü zuerst, dann Overlay) und
Klick-außerhalb-schließt. Kontakt-CTA aus der Nav entfernt.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:13:10 +02:00
fs
3b6f630a72 Unterseiten: Fußball-Übersicht, Mannschaften, Jugend, Verein, Rechtliches
Neue Seiten + Routen: fussball, fussball/{erste-mannschaft,zweite-mannschaft,
damen}, jugendfussball, verein, impressum, datenschutz. Dazu die Komponenten
team, team-cards/-roster/-photo/-bento, faq/faq-contact, key-facts, age-groups,
cta-band, training-location und der contact-slider.

Daten in teams/fussball/jugend/verein.json; club.json um Vorstand, Bankdaten,
Datenschutz-Kontakt erweitert. person-grid bekommt $names-Filter, partner-grid
einen Intro-Stil. Seiten setzen $meta['schema'] via team_/page_schema.
Styles für alle neuen Komponenten in components.css.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:13:04 +02:00
fs
a933b76c4f Banner-Slider auf der Startseite
Komponente banner-slider liest data/banners.json; banner.js übernimmt
Autoplay/Pause/Steuerung (progressive enhancement). Slider sitzt zwischen
Hero und Instagram-Feed. Bilder vorerst als Platzhalter-SVGs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:12:43 +02:00
fs
10b4ede8f1 SEO-Schema-Helper: Breadcrumb, FAQPage, SportsTeam
breadcrumb_schema(), faq_schema(), page_schema() und team_schema() bauen
JSON-LD-Knoten für $meta['schema']. team_schema verweist via #club auf den
Organization-Knoten. Leere FAQ-Paare werden übersprungen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:12:05 +02:00
fs
5170dcb606 Icon-System: icon()-Helper, lokale Bootstrap-Icons, icons-add.php
Inline-SVG-Ausgabe via icon('name', 'klasse', 'label?') aus
public/assets/icons/. Dekorativ (aria-hidden) oder semantisch (role=img).
.icon-Basisklasse in utilities.css (1em, currentColor). bin/icons-add.php
holt neue Icons einzeln von icons.getbootstrap.com.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KDQZ6FuchNUh2bxSW9PeNv
2026-06-19 08:11:58 +02:00
c0616da257 Bild/Text-Sektionen im tinted-Band: padding-block auf clamp(4.5–7.5rem) erhöht
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:24:16 +02:00
5be2a1e6b9 Ansprechpartner: 3er-Reihen mit zentrierten Rest-Reihen (3+2-Layout via Flex)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:19:37 +02:00
3a518f4a65 Hero-Tagline: Outline-Stil entfernt, gefüllt mit 88% Weiß
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:13:40 +02:00
1cb7a21759 Hero Startseite: Editorial-Display-Variante — linksbündig, Kicker mit Akzentbalken, Titel bis 120px, Outline-Tagline, Seitenverlauf, Scroll-Cue
Enthält auch User-Tweak: hero--compact auf 60vh/560px

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:11:11 +02:00
259e209692 Back-to-top-Button: erscheint nach 1,5 Viewporthöhen, Fokus-Management, reduced-motion, 48px-Ziel
Enthält auch User-Upgrade: JSON-LD als @graph mit seitenspezifischen Extra-Knoten

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 23:00:03 +02:00
557fe1c16b CLAUDE.md: Coolvetica-Mindestgröße als Design-Regel festgeschrieben
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:55:40 +02:00
21e2789507 Timeline: Jahreszahlen weiß, Jahres-Nav auf fs-650 (Coolvetica-Lesbarkeitsregel)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:54:49 +02:00
ee4dad2a5f Historie-Hero: Originaltext + Original-Hero-Bild der alten Seite (img-Komponente um Einzeldatei-Modus erweitert)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:53:34 +02:00
efa47d4f60 Vereinshistorie-Seite: kompakter Hero, interaktive Museums-Timeline (Scroll-Reveal, Jahres-Sprungnav), Originalbilder unverändert
routes.php enthält auch die fussball-Route (User-WIP, Seite existiert)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:50:15 +02:00
1ee08b932d tinted-Band generalisiert (.section--tinted) und Ansprechpartner-Sektion hervorgehoben
Enthält auch User-Erweiterung: person-grid mit Abteilungs-Filter/Title/Intro-Props

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:41:57 +02:00
5c4b45a5fe Stats-Band: abgedunkeltes Vereinsgelände-Foto mit weichen Verlaufskanten statt schwarzem Streifen, Zahlen auf fs-900
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:39:09 +02:00
297e4a1546 tinted-Variante: durchgehendes Vollbreite-Band statt Karte; aufeinanderfolgende Bänder verschmelzen
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:35:24 +02:00
f55bd40a1e Split-Sektionen: tinted-Variante (sanft aufgehelltes Panel) für Historie + Sportheim
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:31:58 +02:00
51149e8c5f Platzhalter-Avatar: AdobeStock-Frauenavatar (von alter Seite, lokal optimiert 11 KB) statt Initialen-Fallback
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:28:51 +02:00
d757fe1043 Person-Card: geschlechtsneutraler Initialen-Avatar als Fallback (statt männlichem Foto-Platzhalter), platzhalter.jpg entfernt
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:24:45 +02:00
335749b6d0 Ansprechpartner-Sektion: person-card/person-grid-Komponenten, Daten in ansprechpartner.json, Vereins-Platzhalter statt AdobeStock, tel:/mailto korrekt
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:20:14 +02:00
72c2efaf80 Footer: Verbände-Zeile einzeilig ('Mitglied in:' + Mittelpunkte), Nav-Unterpunkte flach eingereiht (Matchcenter)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:11:57 +02:00
546f1ca059 Footer-Headings auf 28px (neuer Token --fs-650) + Letter-Spacing für Coolvetica-Lesbarkeit
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 22:07:56 +02:00