diff --git a/CLAUDE.md b/CLAUDE.md index da8461a..46d9461 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,7 +11,7 @@ Dieses Dokument beschreibt Architektur, Konventionen und wichtige Implementierun - **Einstiegspunkt:** `index.html` - **Styles:** `css/styles.css` (Layout & Komponenten) + `css/tokens.css` (Design-Tokens) - **Logik:** `js/app.js` (eine einzige Datei) -- **Aktuelle Version:** `v63` (Script-Tag: ` + ``` ### Externe Aufrufe @@ -66,7 +66,7 @@ Die App hat keinen Build-Schritt – getestet wird **die ausgelieferte App**, al ```bash npm install # nur Dev: @playwright/test (exakt gepinnt) npx playwright install chromium # einmalig -npm test # 361 Tests, ~145 s +npm test # 367 Tests, ~145 s npm run test:ui # interaktiver Modus ``` @@ -448,6 +448,23 @@ Geführter Durchlauf durch die Bausteine (`TOUR_STEPS`, `tour = { i, active }`). Schritte mit `needsData` brauchen ein Inventar. Statt still Beispieldaten zu laden – eine Nebenwirkung, die niemand bestellt hat – bietet der Schritt den Import an (`#tour-sample`) und lässt die Entscheidung beim Menschen. Ein Test prüft, dass jedes `target` in der jeweiligen View wirklich existiert; sonst zeigt der Rundgang ins Leere, sobald sich Markup ändert. +### Zivilgesellschaftliche Anknüpfungspunkte + +Die Landesgesetze standen bis v63 nur in **einer** Leserichtung da: als Pflicht der informationspflichtigen Stelle. Für alle anderen – Verein, Stiftung, Initiative – sind dieselben Gesetze das **Werkzeug, um an Daten zu kommen**, die noch nicht offen liegen. Der Lead der Länder-Sektion benennt jetzt beide Richtungen und verweist auf FragDenStaat; die Liste selbst bleibt unverändert. + +Dazu drei Einträge in `PRUEF_WERKZEUGE` und einer in `METHOD_MODELS`: + +| Eintrag | Warum | +|---|---| +| **Musterdatenkatalog** (FITKO/GovData) | ~36.000 Datensätze aus 500+ Kommunen – die schnellste Antwort auf „was veröffentlichen andere?". Hilft beim Zuschnitt des eigenen Inventars, gerade ohne Vorlage | +| **ARX** (Apache 2.0) | die fachliche Referenz für Anonymisierung – und **das, was DatenLotse bewusst nicht tut**: ARX kann generalisieren und unterdrücken, der Risiko-Tab misst nur | +| **OParl 1.1** (OKF Deutschland, CC BY 3.0 DE) | Schnittstelle für kommunale Ratsinformationssysteme; relevant, wenn Gremiendaten nachgenutzt oder beschrieben werden | +| **DigComp** (EU JRC, CC BY 4.0) | **Ergänzung, kein Ersatz** für Data Orchard: DigComp beschreibt die Kompetenzen einzelner Personen, die Dimension „Können & Kapazität" fragt nach der Organisation. Frei lizenziert, anders als CC BY-NC-SA | + +> ⚠️ **Herkunft und Grenze.** Alle Angaben stammen aus dem Recherchebericht des Nutzers. **Nicht** enthalten ist die Initiative Transparente Zivilgesellschaft – sie stammte aus einer eigenen Suche, nicht aus dem Bericht, und der Wortlaut ihrer zehn Punkte ließ sich nicht am Original prüfen. Ebenfalls **nicht** übernommen: die im Bericht erwähnte geplante IFG-Einschränkung. Sie beruht dort ausdrücklich nur auf zivilgesellschaftlichen Quellen, ein amtlicher Entwurf lag nicht vor – ein Werkzeug, das bewusst keine Jahreszahlen führt, darf erst recht keinen Gesetzentwurf behaupten, den es nicht gibt. + +⚠️ **Regel für `PRUEF_WERKZEUGE`:** jede Adresse zeigt auf die Stelle, die das Werkzeug bzw. den Normtext **selbst** herausgibt – nie auf eine Sekundärquelle. Der Test führt dafür seit v64 eine Zuordnung Name → Host statt einer Host-Liste: ein neuer Eintrag erzwingt eine bewusste Entscheidung. + ### Kommunale Informationsfreiheitssatzungen `KOMMUNAL_SATZUNGEN` + Sektion `#wissen-sec-kommunal`. Wo ein Landesgesetz fehlt (Bayern, Niedersachsen), können Kommunen Informationsfreiheit über ihre Satzungsautonomie einführen. @@ -657,6 +674,7 @@ Nach Änderungen an `app.js` `?v=N` im Script-Tag **und** die `v{N}` im Footer e | v16 | Daten-Kompass (Herzstück) – eigene View + Hero-Haupt-CTA (Topbar-„Loslegen" zeigt ebenfalls darauf): ausführliche Open-Data-Reifegrad-Checkliste nach ODRA / EU Open Data Maturity / 5-Sterne / DCAT-AP.de / DSGVO·FAIR (7 Dimensionen, Quellenangaben), Status je Item mit Score & Ampel, Vorbelegung aus dem App-Stand, adaptive Sprünge in die passenden Bausteine, Persistenz (`datenlotse_kompass`) und PDF-Export; leeres „Loslegen"-Platzhalter-Modal entfernt | | v17 | Weiterer Ausbau (1/4) – Inventar Suche, Filter & Sortierung: `renderInventory()` in `renderInventory()` + `renderInventoryBody()` aufgeteilt; `.inv-controls` (Volltextsuche + Schutzbedarf-/Clearing-Ampel-Filter + Sortierung Titel/Vollständigkeit) über `invFilter`-State und `filteredInventory()`; der echte `idx` wird durch den Filter mitgeführt, sodass Editieren über gefilterten Teilmengen weiterhin den richtigen Datensatz trifft; Live-Meta „X von Y" + Empty-State | | v18 | Weiterer Ausbau (2/4) – Pseudonymisierung erweitert: drei neue Muster (Sozialversicherungsnummer, Steuer-ID *kontextgetriggert*, Kfz-Kennzeichen), Aktenzeichen um Geschäftszeichen/„Gz." und buchstabenhaltige Kerne erweitert, zusätzliche Geburtsdatum-Trigger („Geburtsdatum"/„Geburtstag"); Mapping-Export als CSV (`buildPseudoMappingCSV` + Button im Mapping-Kopf); Demo-Text und Grenzen-Liste aktualisiert; verifiziert auf Determinismus, Platzhalter-Konsistenz und Null-Falschtreffer auf neutralem Verwaltungstext | +| v64 | **Der zivilgesellschaftliche Anknüpfungspunkt – aus den Quellen, die wirklich vorlagen.** Die auffälligste Lücke war keine fehlende Liste, sondern eine fehlende Leserichtung: die 16 Landesgesetze standen nur als Pflicht der informationspflichtigen Stelle da. Für einen Verein sind dieselben Gesetze das Werkzeug, um an Daten zu kommen – der Lead benennt jetzt beide Richtungen und verweist auf FragDenStaat. Dazu drei Werkzeuge aus dem Bericht: der **Musterdatenkatalog** als Antwort auf „was veröffentlichen andere?", **ARX** als das, was DatenLotse bewusst nicht tut (generalisieren und unterdrücken statt nur messen), und **OParl 1.1** für Ratsinformationen. **DigComp** kommt als frei lizenzierte Ergänzung zu Data Orchard dazu – ausdrücklich nicht als Ersatz, denn es beschreibt einzelne Personen, während die Dimension nach der Organisation fragt. Nicht übernommen: die geplante IFG-Einschränkung (im Bericht selbst nur advocacy-belegt, kein amtlicher Entwurf) und die Initiative Transparente Zivilgesellschaft (stammte aus einer eigenen Suche, nicht aus dem Bericht). Beim Einfügen fiel auf, dass der Bestandstest für die Werkzeugliste eine **Host-Liste** kodierte; die eigentliche Regel ist „jede Adresse zeigt auf die herausgebende Stelle selbst" – der Test führt jetzt eine Zuordnung Name → Host, sodass ein neuer Eintrag eine Entscheidung erzwingt. 6 neue Tests. Ein Mutationslauf lief zunächst wirkungslos durch, weil das deutsche Schlusszeichen den Python-String beendete, ein zweiter blieb grün, weil mein Test auf „ergänzt" prüfte – das steht auch im mutierten Text. Erst die Prüfung auf „statt sie zu ersetzen" machte ihn rot. | | v63 | **Die Vollständigkeits-Zahl war zu freundlich.** `completeness()` zählte gefüllte Pflichtfelder – ein Datensatz mit allen Pflichtangaben stand auf 100 %, auch ohne Schlagwörter, ohne Zeitraum und nur als PDF. Genau dagegen richtet sich der Leitgedanke der Metadata Quality Assurance von data.europa.eu. Die Zahl folgt jetzt deren Schema: fünf FAIR-Dimensionen, 405 Punkte, 18 Einzelprüfungen. **Ersatz statt drittes Maß** – der Funktionsname bleibt, damit Badge, Durchschnitt, Sortierung, Dashboard und Bericht weiter an genau einer graduellen Zahl hängen. Ein frischer Import fällt damit von ~83 % auf ~46 %; das ist der Zweck. Sauber getrennt ist, was übernommen wurde: die **Dimensionsgewichte** stammen aus der Methodik, die **Zuordnung der Einzelprüfungen** ist eigene Zutat – ein Test pinnt die Gewichte wörtlich und prüft, dass jede Dimension ihr Maximum ausschöpft. Ausdrücklich benannt ist auch, was der Wert **nicht** ist: die MQA ruft URLs ab, DatenLotse macht keine Netzaufrufe und prüft nur Vorhandensein und Wohlgeformtheit. Der stärkste Test geht die 18 Prüfungen einzeln durch und misst, ob jede ihre vollen Punkte ausmacht – eine wirkungslose Prüfung fällt sofort auf. Beim Bauen zeigte sich nebenbei, dass `empty()` zweimal wortgleich als lokale Hilfe existierte; jetzt einmal modulweit. 8 neue Tests, drei bestehende auf die neue Semantik umgeschrieben statt gelockert. Ein erster Mutationsversuch war zu schwach gewählt und lief grün durch – erst die schärfere Fassung (Positivliste akzeptiert alles) machte ihn rot. | | v62 | **Rechtslage nachgezogen – mit offengelegter Herkunft.** `LEGAL_BASIS` kannte weder den **Data Act** noch den **Data Governance Act**, obwohl beide inzwischen anwendbar sind, und der Eintrag zu § 12a EGovG stand noch auf dem Stand vor dem OZG-Änderungsgesetz (Ausweitung auf die „Behörden des Bundes", Open-Data-Koordinatoren, Berichtspflicht). Der interessanteste Zugewinn ist **DGG Kapitel II**: das Statistische Bundesamt ist dort zentrale Informationsstelle für die Weiterverwendung geschützter Verwaltungsdaten und unterstützt ausdrücklich bei Anonymisierung und Pseudonymisierung – das ist der amtliche Anknüpfungspunkt zu Modul 3a und 3b. Beim Data Act war die Formulierung heikel: Kapitel V verpflichtet nur bei **außergewöhnlicher Notwendigkeit**, und ein Eintrag, der das verschweigt, weckt die Erwartung eines allgemeinen Datenzugangs; ein Test hält den Vorbehalt fest. **Zur Herkunft:** die Angaben stammen aus einem Recherchebericht des Nutzers, nicht aus eigener Prüfung an der amtlichen Quelle – die Netzwerkrichtlinie sperrt EUR-Lex und gesetze-im-internet.de. Verlinkt wurde deshalb nur, was sich aus dem dokumentierten CELEX-Schema sicher bilden lässt; DADG und DGG stehen im Text, aber ohne Link, damit keine geratene Fundstelle als amtliche Quelle erscheint. Dazu: die Prüfwerkzeuge nannten die **DCAT-AP.de-Spezifikation 2.0**, aktuell ist 3.0 – das Konventionenhandbuch bleibt dagegen ausdrücklich bei 2.0. 6 neue Tests, drei Mutationen geprüft. | | v61 | **Derselbe Fehler, zwei Tabs weiter.** Nachdem v57 im Risiko-Tab drei Fehlerklassen behoben hatte, lag die Frage nahe, ob die Schwester-Tabs sie auch tragen. Eine gezielte Probe sagte: ja, alle drei. Am schwersten wiegt die Spaltenbereinigung, weil dort ein **Download** daran hängt: wer nach dem Bereinigen eine zweite Spalte auf „ganze Spalte ersetzen" stellt, sah weiterhin das alte Ergebnis – und der Knopf „Bereinigte CSV" lieferte eine Datei, in der der Wert noch im Klartext stand, obwohl die Konfiguration daneben etwas anderes behauptete. Nachgemessen: Konfiguration `{0: ganz, 1: ganz}`, Datei `Name,Ort\n[PERSON_1],Leipzig`. Im Freitext-Tab dasselbe Muster – die bereinigte Fassung blieb nach einer Textänderung stehen, samt Download. Dazu der Fokusverlust beim Umschalten einer Spaltenbehandlung, weil `renderPseudoCsv()` die ganze Box neu baute. Alle drei behoben; die Regel steht jetzt als Konvention in der Doku, weil sie zum dritten Mal aufgetreten ist. 5 neue Tests, drei Mutationen einzeln geprüft. | diff --git a/README.md b/README.md index 5ea537c..56e7616 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ | 🔗 | **Konsistenzprüfung über den Bestand** | Findet, was der Blick auf den einzelnen Datensatz nicht sieht: doppelte Identifier, doppelte Titel, zweimal dieselbe Zugriffs-URL und Schreibvarianten beim Publisher. Gemeldet wird jeweils der Abweichler, mit Sprung zur betroffenen Karte | | ⚖️ | **Hochwertige Datensätze (HVD)** | Für Datensätze, die unter die Durchführungsverordnung (EU) 2023/138 fallen, gelten **verbindliche** Vorgaben: kostenfrei, maschinenlesbar, über eine API, Lizenz nicht restriktiver als CC BY 4.0. Die Qualitätsprüfung meldet Verstöße deshalb als Fehler statt als Warnung. Zur Auswahl steht das **vollständige amtliche Vokabular** der EU-Publikationsstelle (96 Konzepte, gruppiert nach den sechs Kategorien) – die Spezifikation empfiehlt den genauesten Begriff. Das Werkzeug **schlägt eine Einstufung vor, nimmt sie aber niemandem ab**: ob die Verordnung greift, ist eine Rechtsfrage | | ✅ | **DCAT-AP.de-Qualitätsprüfung** | Publish-Ready-Check je Datensatz: fehlende Pflichtfelder als **Fehler**, fehlende Empfehlungsfelder und Werteprüfungen (offene Lizenz, kontrolliertes Vokabular, E-Mail im Ansprechpartner) als **Warnungen** – mit Ampel-Übersicht und direktem Sprung zum Bearbeiten im Inventar | -| 📚 | **Wissens- & Methodik-Center** | In-App-Nachschlagewerk mit Live-Filter über alles: **20 Glossar-Begriffe**, **11 Rechtsgrundlagen** (Bund/EU mit amtlichen Links zu gesetze-im-internet.de bzw. EUR-Lex, inklusive der HVD-Durchführungsverordnung), **alle 16 Landesregelungen** (Transparenz- vs. Informationsfreiheitsgesetz, jeweils mit amtlicher Fundstelle und eigenem Bundesland-Filter), **kommunale Informationsfreiheitssatzungen** für die Länder ohne Landesgesetz, **Prüfwerkzeuge & Normtexte** (offizieller EU-SHACL-Validator, DCAT-AP.de-Spezifikation und Konventionenhandbuch) und die **6 Reifegrad-Modelle** hinter dem Kompass – lokal, ausdrücklich keine Rechtsberatung | +| 📚 | **Wissens- & Methodik-Center** | In-App-Nachschlagewerk mit Live-Filter über alles: **20 Glossar-Begriffe**, **11 Rechtsgrundlagen** (Bund/EU mit amtlichen Links zu gesetze-im-internet.de bzw. EUR-Lex, inklusive der HVD-Durchführungsverordnung), **alle 16 Landesregelungen** (Transparenz- vs. Informationsfreiheitsgesetz, jeweils mit amtlicher Fundstelle und eigenem Bundesland-Filter), **kommunale Informationsfreiheitssatzungen** für die Länder ohne Landesgesetz, **Prüfwerkzeuge & Normtexte** (offizieller EU-SHACL-Validator, DCAT-AP.de-Spezifikation und Konventionenhandbuch) und die **7 Reifegrad-Modelle** hinter dem Kompass – lokal, ausdrücklich keine Rechtsberatung | | 🧾 | **Status auf einen Blick** | Einseitige Zusammenfassung über alle Bausteine – Reifegrade, Inventar, Publikationsreife, Clearing-Verteilung und die nächsten Schritte. Für Leitungsrunden und Gremien; funktioniert auch ohne Inventar, weil der leere Stand ebenfalls eine Aussage ist | | 🔒 | **Eigene Datenschutzerklärung** | Unter `/datenschutz/`, aus demselben Generator wie die Wissensseiten. Sie beschreibt, was das Werkzeug wirklich tut: Local Storage statt Server, GitHub Pages als Hoster samt US-Transfer, die anonyme Seitenzählung mit dem, was sie sieht und was nicht, keine Cookies, keine Schriften-CDN, kein KI-Dienst – und der Hinweis, dass sich all das im Quelltext nachprüfen lässt | | 📄 | **Vorlagen & Musterdokumente** | Fertige Dokumente lokal erzeugt: Open-Data-Richtlinie und DSFA-Kurz-Checkliste (Muster) sowie aus dem Inventar generierte Veröffentlichungs-Freigabe-Formulare und ein VVT-Auszug der DSGVO-relevanten Datensätze – als PDF druckbar oder als Markdown/CSV ladbar | @@ -116,7 +116,7 @@ Die App selbst bleibt abhängigkeitsfrei; für die Tests wird einmalig Playwrigh ```bash npm install # nur Dev: @playwright/test npx playwright install chromium -npm test # 361 Tests, ~145 s +npm test # 367 Tests, ~145 s npm run test:ui # interaktiver Modus ``` @@ -306,7 +306,7 @@ datenlotse/ │ ├── sample-landkreis.csv # Beispiel: fiktive Kreisverwaltung (12 Datensätze) │ ├── sample-landesbehoerde.csv # Beispiel: fiktive Landesebene (12 Datensätze) │ └── template.csv # Leere Vorlage zum eigenen Befüllen -├── tests/ # Playwright-End-to-End-Tests (361 Tests) +├── tests/ # Playwright-End-to-End-Tests (367 Tests) │ ├── helpers.js # openApp/loadSample/Download-Helfer │ ├── smoke.spec.js # Views, Routing, Dashboard, HTML-Validität │ ├── import.spec.js # CSV-Parser, Ableitung, Formel-Injection diff --git a/assets/fonts/fa/icons.min.css b/assets/fonts/fa/icons.min.css index 8b57222..bd49d18 100644 --- a/assets/fonts/fa/icons.min.css +++ b/assets/fonts/fa/icons.min.css @@ -8,5 +8,5 @@ */ @font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:400;font-display:swap;src:url(../webfonts/fa-regular-400.subset.woff2) format("woff2")} @font-face{font-family:"Font Awesome 6 Free";font-style:normal;font-weight:900;font-display:swap;src:url(../webfonts/fa-solid-900.subset.woff2) format("woff2")} -.fa{font-family:var(--fa-style-family,"Font Awesome 6 Free");font-weight:var(--fa-style,900)}.fa,.fa-brands,.fa-regular,.fa-solid,.fab,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(--fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-brands:before,.fa-regular:before,.fa-solid:before,.fa:before,.fab:before,.far:before,.fas:before{content:var(--fa)}.fa-classic,.fa-regular,.fa-solid,.far,.fas{font-family:"Font Awesome 6 Free"}.fa-brands,.fab{font-family:"Font Awesome 6 Brands"}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.08em) var(--fa-border-style,solid) var(--fa-border-color,#eee);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{animation-name:fa-beat;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{animation-name:fa-bounce;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{animation-name:fa-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{animation-name:fa-beat-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{animation-name:fa-flip;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{animation-name:fa-shake;animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{animation-name:fa-spin;animation-duration:var(--fa-animation-duration,2s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{animation-name:fa-spin;animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{animation-delay:-1ms;animation-duration:1ms;animation-iteration-count:1;transition-delay:0s;transition-duration:0s}}@keyframes fa-beat{0%,90%{transform:scale(1)}45%{transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-bounce{0%{transform:scale(1) translateY(0)}10%{transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{transform:scale(1) translateY(0)}to{transform:scale(1) translateY(0)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);transform:scale(1)}50%{opacity:1;transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-flip{50%{transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-shake{0%{transform:rotate(-15deg)}4%{transform:rotate(15deg)}8%,24%{transform:rotate(-18deg)}12%,28%{transform:rotate(18deg)}16%{transform:rotate(-22deg)}20%{transform:rotate(22deg)}32%{transform:rotate(-12deg)}36%{transform:rotate(12deg)}40%,to{transform:rotate(0deg)}}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}.fa-rotate-by{transform:rotate(var(--fa-rotate-angle,0))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%;z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)}.fa-trash-can{--fa:"\f2ed"}.fa-file-lines{--fa:"\f15c"}.fa-file-csv{--fa:"\f6dd"}.fa-gavel{--fa:"\f0e3"}.fa-table{--fa:"\f0ce"}.fa-compass{--fa:"\f14e"}.fa-bars{--fa:"\f0c9"}.fa-lightbulb{--fa:"\f0eb"}.fa-circle-exclamation{--fa:"\f06a"}.fa-square-check{--fa:"\f14a"}.fa-lock{--fa:"\f023"}.fa-share-nodes{--fa:"\f1e0"}.fa-bookmark{--fa:"\f02e"}.fa-wand-magic-sparkles{--fa:"\e2ca"}.fa-globe{--fa:"\f0ac"}.fa-spell-check{--fa:"\f891"}.fa-city{--fa:"\f64f"}.fa-file-arrow-up{--fa:"\f574"}.fa-map-location-dot{--fa:"\f5a0"}.fa-table-columns{--fa:"\f0db"}.fa-handshake{--fa:"\f2b5"}.fa-circle-check{--fa:"\f058"}.fa-file-import{--fa:"\f56f"}.fa-scroll{--fa:"\f70e"}.fa-shield-halved{--fa:"\f3ed"}.fa-square{--fa:"\f0c8"}.fa-question{--fa:"\3f"}.fa-hand-holding-heart{--fa:"\f4be"}.fa-arrow-up-right-from-square{--fa:"\f08e"}.fa-chart-pie{--fa:"\f200"}.fa-chart-line{--fa:"\f201"}.fa-arrow-right{--fa:"\f061"}.fa-recycle{--fa:"\f1b8"}.fa-clipboard-check{--fa:"\f46c"}.fa-circle-question{--fa:"\f059"}.fa-route{--fa:"\f4d7"}.fa-pen{--fa:"\f304"}.fa-cubes{--fa:"\f1b3"}.fa-arrow-left{--fa:"\f060"}.fa-align-left{--fa:"\f036"}.fa-circle-nodes{--fa:"\e4e2"}.fa-circle-info{--fa:"\f05a"}.fa-landmark{--fa:"\f66f"}.fa-check-double{--fa:"\f560"}.fa-minus{--fa:"\f068"}.fa-flask{--fa:"\f0c3"}.fa-download{--fa:"\f019"}.fa-file-circle-check{--fa:"\e5a0"}.fa-id-card{--fa:"\f2c2"}.fa-house{--fa:"\f015"}.fa-file-arrow-down{--fa:"\f56d"}.fa-arrows-turn-to-dots{--fa:"\e4c1"}.fa-book-open-reader{--fa:"\f5da"}.fa-gauge-high{--fa:"\f625"}.fa-boxes-stacked{--fa:"\f468"}.fa-link{--fa:"\f0c1"}.fa-play{--fa:"\f04b"}.fa-magnifying-glass{--fa:"\f002"}.fa-chevron-down{--fa:"\f078"}.fa-code-compare{--fa:"\e13a"}.fa-list-check{--fa:"\f0ae"}.fa-user-shield{--fa:"\f505"}.fa-diagram-project{--fa:"\f542"}.fa-plus{--fa:"\2b"}.fa-xmark{--fa:"\f00d"}.fa-ruler-combined{--fa:"\f546"}.fa-map{--fa:"\f279"}.fa-rocket{--fa:"\f135"}.fa-arrow-trend-up{--fa:"\e098"}.fa-traffic-light{--fa:"\f637"}.fa-rotate{--fa:"\f2f1"}.fa-gears{--fa:"\f085"}.fa-award{--fa:"\f559"}.fa-file-export{--fa:"\f56e"}.fa-arrow-trend-down{--fa:"\e097"}.fa-scale-balanced{--fa:"\f24e"}.fa-table-list{--fa:"\f00b"}.fa-book{--fa:"\f02d"}.fa-diagram-successor{--fa:"\e47a"}.fa-triangle-exclamation{--fa:"\f071"}.fa-database{--fa:"\f1c0"}.fa-circle-xmark{--fa:"\f057"}.fa-arrows-spin{--fa:"\e4bb"}.fa-print{--fa:"\f02f"}.fa-users-gear{--fa:"\f509"}.fa-building-columns{--fa:"\f19c"}.fa-graduation-cap{--fa:"\f19d"} +.fa{font-family:var(--fa-style-family,"Font Awesome 6 Free");font-weight:var(--fa-style,900)}.fa,.fa-brands,.fa-regular,.fa-solid,.fab,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:var(--fa-display,inline-block);font-style:normal;font-variant:normal;line-height:1;text-rendering:auto}.fa-brands:before,.fa-regular:before,.fa-solid:before,.fa:before,.fab:before,.far:before,.fas:before{content:var(--fa)}.fa-classic,.fa-regular,.fa-solid,.far,.fas{font-family:"Font Awesome 6 Free"}.fa-brands,.fab{font-family:"Font Awesome 6 Brands"}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-2xs{font-size:.625em;line-height:.1em;vertical-align:.225em}.fa-xs{font-size:.75em;line-height:.08333em;vertical-align:.125em}.fa-sm{font-size:.875em;line-height:.07143em;vertical-align:.05357em}.fa-lg{font-size:1.25em;line-height:.05em;vertical-align:-.075em}.fa-xl{font-size:1.5em;line-height:.04167em;vertical-align:-.125em}.fa-2xl{font-size:2em;line-height:.03125em;vertical-align:-.1875em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:var(--fa-li-margin,2.5em);padding-left:0}.fa-ul>li{position:relative}.fa-li{left:calc(var(--fa-li-width, 2em)*-1);position:absolute;text-align:center;width:var(--fa-li-width,2em);line-height:inherit}.fa-border{border-radius:var(--fa-border-radius,.1em);border:var(--fa-border-width,.08em) var(--fa-border-style,solid) var(--fa-border-color,#eee);padding:var(--fa-border-padding,.2em .25em .15em)}.fa-pull-left{float:left;margin-right:var(--fa-pull-margin,.3em)}.fa-pull-right{float:right;margin-left:var(--fa-pull-margin,.3em)}.fa-beat{animation-name:fa-beat;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-bounce{animation-name:fa-bounce;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.28,.84,.42,1))}.fa-fade{animation-name:fa-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-beat-fade,.fa-fade{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s)}.fa-beat-fade{animation-name:fa-beat-fade;animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,cubic-bezier(.4,0,.6,1))}.fa-flip{animation-name:fa-flip;animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,ease-in-out)}.fa-shake{animation-name:fa-shake;animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-shake,.fa-spin{animation-delay:var(--fa-animation-delay,0s);animation-direction:var(--fa-animation-direction,normal)}.fa-spin{animation-name:fa-spin;animation-duration:var(--fa-animation-duration,2s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,linear)}.fa-spin-reverse{--fa-animation-direction:reverse}.fa-pulse,.fa-spin-pulse{animation-name:fa-spin;animation-direction:var(--fa-animation-direction,normal);animation-duration:var(--fa-animation-duration,1s);animation-iteration-count:var(--fa-animation-iteration-count,infinite);animation-timing-function:var(--fa-animation-timing,steps(8))}@media (prefers-reduced-motion:reduce){.fa-beat,.fa-beat-fade,.fa-bounce,.fa-fade,.fa-flip,.fa-pulse,.fa-shake,.fa-spin,.fa-spin-pulse{animation-delay:-1ms;animation-duration:1ms;animation-iteration-count:1;transition-delay:0s;transition-duration:0s}}@keyframes fa-beat{0%,90%{transform:scale(1)}45%{transform:scale(var(--fa-beat-scale,1.25))}}@keyframes fa-bounce{0%{transform:scale(1) translateY(0)}10%{transform:scale(var(--fa-bounce-start-scale-x,1.1),var(--fa-bounce-start-scale-y,.9)) translateY(0)}30%{transform:scale(var(--fa-bounce-jump-scale-x,.9),var(--fa-bounce-jump-scale-y,1.1)) translateY(var(--fa-bounce-height,-.5em))}50%{transform:scale(var(--fa-bounce-land-scale-x,1.05),var(--fa-bounce-land-scale-y,.95)) translateY(0)}57%{transform:scale(1) translateY(var(--fa-bounce-rebound,-.125em))}64%{transform:scale(1) translateY(0)}to{transform:scale(1) translateY(0)}}@keyframes fa-fade{50%{opacity:var(--fa-fade-opacity,.4)}}@keyframes fa-beat-fade{0%,to{opacity:var(--fa-beat-fade-opacity,.4);transform:scale(1)}50%{opacity:1;transform:scale(var(--fa-beat-fade-scale,1.125))}}@keyframes fa-flip{50%{transform:rotate3d(var(--fa-flip-x,0),var(--fa-flip-y,1),var(--fa-flip-z,0),var(--fa-flip-angle,-180deg))}}@keyframes fa-shake{0%{transform:rotate(-15deg)}4%{transform:rotate(15deg)}8%,24%{transform:rotate(-18deg)}12%,28%{transform:rotate(18deg)}16%{transform:rotate(-22deg)}20%{transform:rotate(22deg)}32%{transform:rotate(-12deg)}36%{transform:rotate(12deg)}40%,to{transform:rotate(0deg)}}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{transform:rotate(90deg)}.fa-rotate-180{transform:rotate(180deg)}.fa-rotate-270{transform:rotate(270deg)}.fa-flip-horizontal{transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}.fa-rotate-by{transform:rotate(var(--fa-rotate-angle,0))}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%;z-index:var(--fa-stack-z-index,auto)}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:var(--fa-inverse,#fff)}.fa-trash-can{--fa:"\f2ed"}.fa-file-lines{--fa:"\f15c"}.fa-file-csv{--fa:"\f6dd"}.fa-gavel{--fa:"\f0e3"}.fa-table{--fa:"\f0ce"}.fa-compass{--fa:"\f14e"}.fa-bars{--fa:"\f0c9"}.fa-lightbulb{--fa:"\f0eb"}.fa-circle-exclamation{--fa:"\f06a"}.fa-square-check{--fa:"\f14a"}.fa-lock{--fa:"\f023"}.fa-share-nodes{--fa:"\f1e0"}.fa-bookmark{--fa:"\f02e"}.fa-wand-magic-sparkles{--fa:"\e2ca"}.fa-globe{--fa:"\f0ac"}.fa-spell-check{--fa:"\f891"}.fa-city{--fa:"\f64f"}.fa-file-arrow-up{--fa:"\f574"}.fa-map-location-dot{--fa:"\f5a0"}.fa-table-columns{--fa:"\f0db"}.fa-handshake{--fa:"\f2b5"}.fa-circle-check{--fa:"\f058"}.fa-file-import{--fa:"\f56f"}.fa-scroll{--fa:"\f70e"}.fa-shield-halved{--fa:"\f3ed"}.fa-square{--fa:"\f0c8"}.fa-question{--fa:"\3f"}.fa-hand-holding-heart{--fa:"\f4be"}.fa-arrow-up-right-from-square{--fa:"\f08e"}.fa-chart-pie{--fa:"\f200"}.fa-chart-line{--fa:"\f201"}.fa-arrow-right{--fa:"\f061"}.fa-recycle{--fa:"\f1b8"}.fa-clipboard-check{--fa:"\f46c"}.fa-circle-question{--fa:"\f059"}.fa-route{--fa:"\f4d7"}.fa-pen{--fa:"\f304"}.fa-cubes{--fa:"\f1b3"}.fa-arrow-left{--fa:"\f060"}.fa-align-left{--fa:"\f036"}.fa-circle-nodes{--fa:"\e4e2"}.fa-circle-info{--fa:"\f05a"}.fa-landmark{--fa:"\f66f"}.fa-check-double{--fa:"\f560"}.fa-minus{--fa:"\f068"}.fa-flask{--fa:"\f0c3"}.fa-download{--fa:"\f019"}.fa-file-circle-check{--fa:"\e5a0"}.fa-id-card{--fa:"\f2c2"}.fa-house{--fa:"\f015"}.fa-arrow-right-arrow-left{--fa:"\f0ec"}.fa-file-arrow-down{--fa:"\f56d"}.fa-arrows-turn-to-dots{--fa:"\e4c1"}.fa-book-open-reader{--fa:"\f5da"}.fa-gauge-high{--fa:"\f625"}.fa-boxes-stacked{--fa:"\f468"}.fa-link{--fa:"\f0c1"}.fa-play{--fa:"\f04b"}.fa-magnifying-glass{--fa:"\f002"}.fa-chevron-down{--fa:"\f078"}.fa-code-compare{--fa:"\e13a"}.fa-list-check{--fa:"\f0ae"}.fa-user-shield{--fa:"\f505"}.fa-diagram-project{--fa:"\f542"}.fa-plus{--fa:"\2b"}.fa-xmark{--fa:"\f00d"}.fa-ruler-combined{--fa:"\f546"}.fa-map{--fa:"\f279"}.fa-rocket{--fa:"\f135"}.fa-arrow-trend-up{--fa:"\e098"}.fa-traffic-light{--fa:"\f637"}.fa-rotate{--fa:"\f2f1"}.fa-gears{--fa:"\f085"}.fa-award{--fa:"\f559"}.fa-file-export{--fa:"\f56e"}.fa-arrow-trend-down{--fa:"\e097"}.fa-scale-balanced{--fa:"\f24e"}.fa-table-list{--fa:"\f00b"}.fa-book{--fa:"\f02d"}.fa-diagram-successor{--fa:"\e47a"}.fa-triangle-exclamation{--fa:"\f071"}.fa-database{--fa:"\f1c0"}.fa-circle-xmark{--fa:"\f057"}.fa-arrows-spin{--fa:"\e4bb"}.fa-print{--fa:"\f02f"}.fa-users-gear{--fa:"\f509"}.fa-building-columns{--fa:"\f19c"}.fa-graduation-cap{--fa:"\f19d"} .fa-sr-only,.fa-sr-only-focusable:not(:focus),.sr-only,.sr-only-focusable:not(:focus){position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}:host,:root{--fa-style-family-brands:"Font Awesome 6 Brands";--fa-font-brands:normal 400 1em/1 "Font Awesome 6 Brands"}.fa-brands,.fab{font-weight:400}:host,:root{--fa-font-regular:normal 400 1em/1 "Font Awesome 6 Free"}.fa-regular,.far{font-weight:400}:host,:root{--fa-style-family-classic:"Font Awesome 6 Free";--fa-font-solid:normal 900 1em/1 "Font Awesome 6 Free"}.fa-solid,.fas{font-weight:900} diff --git a/assets/fonts/webfonts/fa-regular-400.subset.woff2 b/assets/fonts/webfonts/fa-regular-400.subset.woff2 index 6558aea..34f3738 100644 Binary files a/assets/fonts/webfonts/fa-regular-400.subset.woff2 and b/assets/fonts/webfonts/fa-regular-400.subset.woff2 differ diff --git a/assets/fonts/webfonts/fa-solid-900.subset.woff2 b/assets/fonts/webfonts/fa-solid-900.subset.woff2 index 0fb9992..94386dd 100644 Binary files a/assets/fonts/webfonts/fa-solid-900.subset.woff2 and b/assets/fonts/webfonts/fa-solid-900.subset.woff2 differ diff --git a/css/styles.css b/css/styles.css index c127d4f..db2e58e 100644 --- a/css/styles.css +++ b/css/styles.css @@ -2562,3 +2562,12 @@ details[open] > .about-summary .about-caret { transform: rotate(180deg); } .module-card:hover, .feature-card:hover { transform: none; } } + +/* Zweite Leserichtung bei den Landesgesetzen: abgesetzt, aber kein Kasten – + es ist eine Ergänzung zum Lead, kein eigener Abschnitt. */ +.know-lead--alt { + border-left: 3px solid var(--c-accent); + padding-left: 12px; + margin-top: 10px; +} +.know-lead--alt i { color: var(--c-accent); } diff --git a/datenschutz/index.html b/datenschutz/index.html index 3b2d6ee..7131936 100644 --- a/datenschutz/index.html +++ b/datenschutz/index.html @@ -42,7 +42,7 @@ } - + diff --git a/index.html b/index.html index c0c7837..bebcdb5 100644 --- a/index.html +++ b/index.html @@ -125,10 +125,10 @@ - + - - + +
@@ -718,6 +718,7 @@Neben dem Bundesrecht gilt Landesrecht – und es unterscheidet sich erheblich. Transparenzgesetze verpflichten zur aktiven Veröffentlichung, Informationsfreiheitsgesetze regeln den Zugang auf Antrag, zwei Länder haben kein allgemeines Gesetz. Maßgeblich ist immer der verlinkte amtliche Text.
+Zwei Leserichtungen. Wer selbst eine informationspflichtige Stelle ist, veröffentlicht nach diesen Gesetzen. Wer es nicht ist – ein Verein, eine Stiftung, eine Initiative – fragt danach an: dieselben Gesetze sind das Werkzeug, um an Daten zu kommen, die noch nicht offen liegen. Anfragen lassen sich über FragDenStaat stellen und veröffentlichen.