diff --git a/app/.metadata b/app/.metadata index a49b961..32850fc 100644 --- a/app/.metadata +++ b/app/.metadata @@ -15,7 +15,7 @@ migration: - platform: root create_revision: 559ffa3f75e7402d65a8def9c28389a9b2e6fe42 base_revision: 559ffa3f75e7402d65a8def9c28389a9b2e6fe42 - - platform: web + - platform: macos create_revision: 559ffa3f75e7402d65a8def9c28389a9b2e6fe42 base_revision: 559ffa3f75e7402d65a8def9c28389a9b2e6fe42 diff --git a/app/lib/pages/legal_page.dart b/app/lib/pages/legal_page.dart deleted file mode 100644 index 5380740..0000000 --- a/app/lib/pages/legal_page.dart +++ /dev/null @@ -1,334 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import '../theme/reclaim_tokens.dart'; -import '../widgets/reclaim_card.dart'; - -/// Combined legal-information page. Six sections in the order -/// a careful reader cares about them: -/// -/// 1. Disclaimer (kein Rechtsrat) — top, most visible -/// 2. EU AI Act Art. 50 (Transparenz) -/// 3. Quellen + Urheberrecht (§ 5 UrhG) -/// 4. Datenschutz (DSGVO Art. 13) -/// 5. Impressum (§ 5 TMG, § 18 MStV) -/// 6. Open Source + Lizenz -/// -/// Each section carries placeholder markers `[PLACEHOLDER]` -/// where the deployment-specific value (Anbieter-Adresse, -/// AVV-Stand, Hosting-Provider) must be filled in before any -/// public publication. The text is drafted conservatively; -/// review by einem Volljuristen bleibt obligatorisch vor der -/// ersten öffentlichen Veröffentlichung. -class LegalPage extends StatelessWidget { - const LegalPage({super.key}); - - @override - Widget build(BuildContext context) { - final t = Theme.of(context).textTheme; - return SingleChildScrollView( - padding: const EdgeInsets.all(ReclaimSpace.xl), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text('Recht & Hinweise', style: t.displaySmall), - const SizedBox(height: ReclaimSpace.xs), - Text( - 'Disclaimer, AI-Act-Transparenz, Urheberrecht, ' - 'Datenschutz, Impressum, Lizenz.', - style: t.bodyLarge?.copyWith(color: ReclaimColors.mute), - ), - const SizedBox(height: ReclaimSpace.lg), - - // 1. Disclaimer - ReclaimCard( - accent: true, - child: _Section( - title: '1. Disclaimer — keine Rechtsberatung', - children: [ - _p(t, - 'Recl∆Im liefert eine methodisch-strukturierte ' - 'Wirkungsanalyse von Rechtsnormen. Die Ergebnisse sind ' - 'KEINE Rechtsberatung im Sinne des ' - 'Rechtsdienstleistungsgesetzes (RDG) und ersetzen weder ' - 'eine individuelle juristische Prüfung noch eine ' - 'Auskunft der zuständigen Behörden oder Kammern.'), - _p(t, - 'Alle Bewertungs-Zahlen tragen eine Evidenz-Tier-Stufe ' - '(T1–T4). Stufen T3/T4 sind nicht peer-reviewed und ' - 'dienen ausschließlich als Hinweis-/Anregung-Wert. ' - 'Eine Reform- oder Streichungs-Empfehlung der ' - 'Anwendung ist ein methodischer Vorschlag, keine ' - 'politische Forderung.'), - _p(t, - 'Die Demo-Daten (fünf Pilot-Normen) sind ' - 'Plausibilitäts-Schätzungen ohne NKR-Validierung. ' - 'Bevor eine Zahl in eine politische Vorlage übernommen ' - 'wird, ist die zugrundeliegende Quelle einzeln zu ' - 'prüfen.'), - ], - ), - ), - const SizedBox(height: ReclaimSpace.lg), - - // 2. AI Act - ReclaimCard( - child: _Section( - title: - '2. EU AI Act — Transparenz nach Art. 50', - children: [ - _p(t, - 'Recl∆Im setzt Künstliche-Intelligenz-Komponenten ein: ' - 'Large-Language-Modelle (LLM) zur Vorschlags-Extraktion ' - 'aus Norm-Texten und zur Synthese von Reform-Texten. ' - 'Jede LLM-erzeugte Aussage ist kennzeichnungspflichtig ' - 'und mit RAG-Quellen-Pflicht hinterlegt; Aussagen ohne ' - 'zitierfähige Quelle werden verworfen.'), - _p(t, - 'Recl∆Im ist KEIN Hochrisiko-KI-System nach Anhang III ' - 'der KI-Verordnung. Die Anwendung trifft keine ' - 'Verwaltungsentscheidungen, generiert keine Rechtsakte, ' - 'beeinflusst nicht direkt Beschäftigungs-, Bildungs- ' - 'oder Sozialleistungs-Verfahren. Sie dient ausschließlich ' - 'der Recherche, Visualisierung und Vorschlags-Generierung ' - 'für menschliche Entscheidungsträger.'), - _p(t, - 'Jede Bewertung durchläuft vor Veröffentlichung einen ' - '`system.approval@^0`-Schritt (Human-in-the-Loop). ' - 'Die menschliche Letztverantwortung ist nicht ' - 'überschreibbar.'), - _p(t, - 'Verwendete Modelle und ihre Digests werden im ' - 'tamper-evidenten Audit-Log des Ch∆In-Hubs gespeichert. ' - 'Reproduzierbarkeit erfolgt mit Temperature ≤ 0,1 und ' - 'festem Prompt-Hash.'), - ], - ), - ), - const SizedBox(height: ReclaimSpace.lg), - - // 3. Quellen + UrhG - ReclaimCard( - child: _Section( - title: '3. Quellen & Urheberrecht (§ 5 UrhG)', - children: [ - _p(t, - 'Die in der Anwendung dargestellten Gesetzes- und ' - 'Verordnungs-Texte sind amtliche Werke im Sinne des ' - '§ 5 UrhG und damit gemeinfrei. Die kanonischen Quellen ' - 'sind verlinkt und durch SHA-256-Prüfsummen im ' - 'Audit-Log nachvollziehbar.'), - _p(t, - 'Primärquellen (T1):'), - _bullet(t, - 'Bundesrecht: gesetze-im-internet.de (BMJ) — § 5 UrhG.'), - _bullet(t, - 'EU-Recht: EUR-Lex (Europäische Kommission) — ' - 'Mehrsprachigkeit nach Verordnung (EU) Nr. 1257/2012.'), - _bullet(t, - 'Landesrecht Berlin: gesetze.berlin.de / ' - 'landesrecht-berlin.de — § 5 UrhG.'), - _p(t, - 'Sekundärquellen (T1/T2):'), - _bullet(t, - 'Nationaler Normenkontrollrat (NKR) — ' - 'Bürokratiekosten-Datenbank, Methodenleitfaden.'), - _bullet(t, - 'Statistisches Bundesamt (DESTATIS) — ' - 'Unternehmensregister, Bürokratiekostenindex.'), - _bullet(t, - 'DIHK, ZDH, IHK Berlin, BDI — ' - 'Verbands-Erhebungen mit Quellen-Angabe.'), - _p(t, - 'Eigene Methodik und Software-Code sind unter ' - 'Apache License 2.0 veröffentlicht; Code-Repository: ' - 'git.flemming.ai/fai/reclaim.'), - ], - ), - ), - const SizedBox(height: ReclaimSpace.lg), - - // 4. Datenschutz - ReclaimCard( - child: _Section( - title: - '4. Datenschutzerklärung (DSGVO Art. 13)', - children: [ - _p(t, - 'Verantwortlicher i.S.d. Art. 4 Nr. 7 DSGVO: ' - '[PLACEHOLDER — Name und Anschrift des Anbieters ' - 'einsetzen].'), - _p(t, - 'Diese Anwendung verarbeitet personenbezogene Daten ' - 'nur in dem Umfang, der für ihren Betrieb erforderlich ' - 'ist. In der Demo-Konfiguration werden keine ' - 'personenbezogenen Daten erhoben; alle Pilot-Norm-Daten ' - 'sind lokal im Browser/auf dem Endgerät gespeichert.'), - _p(t, 'Beim Aufruf der Anwendung über das Internet:'), - _bullet(t, - 'Hosting-Provider: [PLACEHOLDER — etwa Hetzner Online ' - 'GmbH, Falkenstein, EU-Hosting]. AVV nach Art. 28 ' - 'DSGVO abgeschlossen.'), - _bullet(t, - 'Server-Logs (IP-Adresse, User-Agent, Zeitstempel): ' - 'für 7 Tage zur Missbrauchs-Abwehr (Rechtsgrundlage ' - 'Art. 6 Abs. 1 lit. f DSGVO, berechtigtes Interesse).'), - _bullet(t, - 'Kein Tracking, keine Analytics, keine ' - 'Marketing-Cookies.'), - _p(t, - 'Betroffenenrechte (Art. 15–22 DSGVO): Auskunft, ' - 'Berichtigung, Löschung, Einschränkung, Datenübertragbarkeit, ' - 'Widerspruch. Kontakt: ' - '[PLACEHOLDER — Kontakt-E-Mail].'), - _p(t, - 'Beschwerderecht bei der Aufsichtsbehörde: ' - 'Berliner Beauftragte für Datenschutz und ' - 'Informationsfreiheit, Friedrichstr. 219, 10969 Berlin, ' - 'mailbox@datenschutz-berlin.de.'), - ], - ), - ), - const SizedBox(height: ReclaimSpace.lg), - - // 5. Impressum - ReclaimCard( - child: _Section( - title: - '5. Impressum (§ 5 TMG, § 18 Abs. 2 MStV)', - children: [ - _p(t, - 'Anbieter: [PLACEHOLDER — Name].'), - _p(t, - 'Anschrift: [PLACEHOLDER — Straße, Hausnummer, ' - 'PLZ, Ort, Land].'), - _p(t, - 'Kontakt: [PLACEHOLDER — E-Mail, ggf. Telefon].'), - _p(t, - 'Vertretungsberechtigt: [PLACEHOLDER — bei Vereinen, ' - 'GmbHs etc.].'), - _p(t, - 'Verantwortlich für den Inhalt nach § 18 Abs. 2 MStV: ' - '[PLACEHOLDER — Name und ladungsfähige Anschrift, ' - 'in der Regel identisch mit Anbieter].'), - _p(t, - 'Umsatzsteuer-Identifikationsnummer / Register-' - 'eintrag, sofern einschlägig: [PLACEHOLDER].'), - _p(t, - 'Plattform der Europäischen Kommission zur ' - 'außergerichtlichen Online-Streitbeilegung (Art. 14 ' - 'Abs. 1 ODR-VO): ec.europa.eu/consumers/odr. Wir sind ' - 'nicht bereit oder verpflichtet, an ' - 'Streitbeilegungsverfahren vor einer ' - 'Verbraucherschlichtungsstelle teilzunehmen.'), - ], - ), - ), - const SizedBox(height: ReclaimSpace.lg), - - // 6. Open Source - ReclaimCard( - child: _Section( - title: '6. Open Source & Lizenz', - children: [ - _p(t, - 'Recl∆Im ist freie Software, lizenziert unter der ' - 'Apache License, Version 2.0. Der Quelltext, die ' - 'Module und die Methodik sind öffentlich einsehbar ' - 'unter:'), - InkWell( - onTap: () => launchUrl( - Uri.parse('https://git.flemming.ai/fai/reclaim'), - mode: LaunchMode.externalApplication, - ), - child: Text( - 'https://git.flemming.ai/fai/reclaim', - style: t.bodyLarge?.copyWith( - color: ReclaimColors.signal, - decoration: TextDecoration.underline, - fontFamily: ReclaimTypography.mono, - ), - ), - ), - const SizedBox(height: ReclaimSpace.sm), - _p(t, - 'Plattform: Ch∆In (Apache 2.0, ' - 'git.flemming.ai/fai/chain-private). Methodische ' - 'Vorbilder und Lizenz-Hinweise stehen in der Datei ' - 'NOTICE im Repository.'), - _p(t, - 'Beiträge willkommen. DCO Sign-off und Conventional ' - 'Commits in Englisch sind Konvention.'), - ], - ), - ), - const SizedBox(height: ReclaimSpace.xxl), - - Text( - 'Hinweis: Vor der ersten öffentlichen Veröffentlichung ' - 'müssen alle [PLACEHOLDER]-Stellen durch konkrete ' - 'Anbieter-Angaben ersetzt und das gesamte Dokument von ' - 'einem Volljuristen geprüft werden. Diese Seite ist eine ' - 'methodische Vorlage.', - style: t.labelSmall?.copyWith( - color: ReclaimColors.tierT4, - fontStyle: FontStyle.italic, - ), - ), - ], - ), - ); - } -} - -class _Section extends StatelessWidget { - const _Section({required this.title, required this.children}); - - final String title; - final List children; - - @override - Widget build(BuildContext context) { - final t = Theme.of(context).textTheme; - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(title, style: t.headlineSmall), - const SizedBox(height: ReclaimSpace.md), - ...children, - ], - ); - } -} - -Widget _p(TextTheme t, String s) => Padding( - padding: const EdgeInsets.only(bottom: ReclaimSpace.sm), - child: SelectableText(s, style: t.bodyLarge?.copyWith(height: 1.55)), - ); - -Widget _bullet(TextTheme t, String s) => Padding( - padding: const EdgeInsets.only( - left: ReclaimSpace.lg, - bottom: ReclaimSpace.xs, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only(top: 8, right: 10), - child: Container( - width: 5, - height: 5, - decoration: const BoxDecoration( - color: ReclaimColors.signal, - shape: BoxShape.circle, - ), - ), - ), - Expanded( - child: SelectableText(s, - style: t.bodyLarge?.copyWith(height: 1.55)), - ), - ], - ), - ); diff --git a/app/lib/pages/shell_page.dart b/app/lib/pages/shell_page.dart index dfbfd3f..fcbebde 100644 --- a/app/lib/pages/shell_page.dart +++ b/app/lib/pages/shell_page.dart @@ -6,7 +6,6 @@ import '../widgets/delta_mark.dart'; import 'about_page.dart'; import 'heatmap_page.dart'; import 'hub_status_page.dart'; -import 'legal_page.dart'; import 'norms_list_page.dart'; /// App shell with a NavigationRail. Each rail destination is one @@ -31,7 +30,6 @@ class _ShellPageState extends State { NormsListPage(repository: widget.repository), HubStatusPage(repository: widget.repository), const AboutPage(), - const LegalPage(), ]; return Scaffold( @@ -82,11 +80,6 @@ class _ShellPageState extends State { selectedIcon: Icon(Icons.info), label: Text('Methodik'), ), - NavigationRailDestination( - icon: Icon(Icons.gavel_outlined), - selectedIcon: Icon(Icons.gavel), - label: Text('Recht'), - ), ], ), const VerticalDivider(width: 1), diff --git a/app/lib/widgets/demo_banner.dart b/app/lib/widgets/demo_banner.dart index dcf8537..0d41fc0 100644 --- a/app/lib/widgets/demo_banner.dart +++ b/app/lib/widgets/demo_banner.dart @@ -32,9 +32,9 @@ class DemoBanner extends StatelessWidget { const SizedBox(width: ReclaimSpace.sm), Expanded( child: Text( - 'Demo-Daten · KEINE Rechtsberatung · Tier T4. ' - 'Phase 0, ohne Verbands-Erhebung, ohne Juristen- oder ' - 'Beirats-Validierung. Volle Hinweise unter „Recht".', + 'Demo-Daten — Phase 0, ohne Verbands-Erhebung. ' + 'Keine Juristen-Approval, keine Beirats-Validierung. ' + 'Alle Werte tragen Tier T4, bis T1/T2-Pipeline läuft.', style: t.labelSmall?.copyWith( color: ReclaimColors.tierT4, ), diff --git a/app/web/favicon.png b/app/web/favicon.png deleted file mode 100644 index 8aaa46a..0000000 Binary files a/app/web/favicon.png and /dev/null differ diff --git a/app/web/icons/Icon-192.png b/app/web/icons/Icon-192.png deleted file mode 100644 index b749bfe..0000000 Binary files a/app/web/icons/Icon-192.png and /dev/null differ diff --git a/app/web/icons/Icon-512.png b/app/web/icons/Icon-512.png deleted file mode 100644 index 88cfd48..0000000 Binary files a/app/web/icons/Icon-512.png and /dev/null differ diff --git a/app/web/icons/Icon-maskable-192.png b/app/web/icons/Icon-maskable-192.png deleted file mode 100644 index eb9b4d7..0000000 Binary files a/app/web/icons/Icon-maskable-192.png and /dev/null differ diff --git a/app/web/icons/Icon-maskable-512.png b/app/web/icons/Icon-maskable-512.png deleted file mode 100644 index d69c566..0000000 Binary files a/app/web/icons/Icon-maskable-512.png and /dev/null differ diff --git a/app/web/index.html b/app/web/index.html deleted file mode 100644 index ba23a71..0000000 --- a/app/web/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - reclaim_app - - - - - - - diff --git a/app/web/manifest.json b/app/web/manifest.json deleted file mode 100644 index 2bcfb6d..0000000 --- a/app/web/manifest.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "reclaim_app", - "short_name": "reclaim_app", - "start_url": ".", - "display": "standalone", - "background_color": "#0175C2", - "theme_color": "#0175C2", - "description": "A new Flutter project.", - "orientation": "portrait-primary", - "prefer_related_applications": false, - "icons": [ - { - "src": "icons/Icon-192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "icons/Icon-512.png", - "sizes": "512x512", - "type": "image/png" - }, - { - "src": "icons/Icon-maskable-192.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "icons/Icon-maskable-512.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - } - ] -}