diff --git a/MACHBARKEITSSTUDIE.md b/MACHBARKEITSSTUDIE.md index c1603d0..9305180 100644 --- a/MACHBARKEITSSTUDIE.md +++ b/MACHBARKEITSSTUDIE.md @@ -1,4 +1,4 @@ -# F∆I Law-Heatmap — Machbarkeitsstudie & Umsetzungsplan +# Recl∆Im (F∆I) — Machbarkeitsstudie & Umsetzungsplan > Arbeitstitel des Systems: **„Gesetzes-Heatmap" / „Regulierungs-Wirkungsanalyse auf Ch∆In-Basis"** > Auftraggeber-Kontext: MIT AG Digitalisierung & KI-Strategien (Vorsitz Dr. S. Flemming), diff --git a/METHODIK.md b/METHODIK.md index 6afb9a9..bb3d292 100644 --- a/METHODIK.md +++ b/METHODIK.md @@ -1,6 +1,6 @@ # Methodik-Papier — Pflicht-basierte Wirkungsanalyse von Rechtsnormen -> Standalone-Auszug aus der Machbarkeitsstudie F∆I Law-Heatmap, +> Standalone-Auszug aus der Machbarkeitsstudie Recl∆Im (F∆I), > destilliert für AG-Vorlage und Beirats-Konsultation. > > Version v0.1.0 · 2026-06 · Diskussionsgrundlage, AG-intern. diff --git a/RUN.md b/RUN.md index d4c6c08..05501ba 100644 --- a/RUN.md +++ b/RUN.md @@ -1,4 +1,4 @@ -# F∆I Law-Heatmap — Run-Guide (Phase 0) +# Recl∆Im (F∆I) — Run-Guide (Phase 0) > Stand v0.1.0 — Demo-Modus, ohne externe Daten, ohne Hub-Verbindung. @@ -39,7 +39,7 @@ eigene Crate-Verzeichnisse, ABI `chain:platform`, alle Apache 2.0: cd app ./setup.sh # Fonts + flutter pub get ./build-macos.sh # Robust-Build (strippt macOS-xattrs vor CodeSign) -open build/macos/Build/Products/Debug/lawheatmap_app.app +open build/macos/Build/Products/Debug/reclaim_app.app ``` Direkter `flutter run -d macos` funktioniert auch, kann aber bei diff --git a/app/README.md b/app/README.md index 241dc2b..e0c8e2e 100644 --- a/app/README.md +++ b/app/README.md @@ -1,6 +1,6 @@ -# lawheatmap_app +# reclaim_app -F∆I Law-Heatmap client +Recl∆Im (F∆I) client ## Getting Started diff --git a/app/build-macos.sh b/app/build-macos.sh index 87938f6..c4ff804 100755 --- a/app/build-macos.sh +++ b/app/build-macos.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Robust macOS build for the F∆I Law-Heatmap client. +# Robust macOS build for the Recl∆Im (F∆I) client. # # macOS xattrs (especially `com.apple.provenance` on files that # touched iCloud or were downloaded by curl) make Xcode's @@ -30,7 +30,7 @@ flutter build macos --debug \ echo " flutter exited $rc — continuing to xattr+resign step in case the binary linked" } -APP=build/macos/Build/Products/Debug/lawheatmap_app.app +APP=build/macos/Build/Products/Debug/reclaim_app.app if [ ! -d "$APP" ]; then echo "ERROR: $APP does not exist — flutter build failed before linking" exit 1 @@ -45,4 +45,4 @@ echo "[4/4] ad-hoc resign" echo echo "done. Launch with:" echo " open $APP" -echo " # or directly: $APP/Contents/MacOS/lawheatmap_app" +echo " # or directly: $APP/Contents/MacOS/reclaim_app" diff --git a/app/lib/main.dart b/app/lib/main.dart index 82db2aa..733c55c 100644 --- a/app/lib/main.dart +++ b/app/lib/main.dart @@ -5,13 +5,13 @@ import 'data/hub_endpoint.dart'; import 'data/hub_repository.dart'; import 'data/repository.dart'; import 'pages/landing_page.dart'; -import 'theme/lawheatmap_theme.dart'; +import 'theme/reclaim_theme.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); final settings = await HubSettings.load(); final repository = await _pickRepository(settings); - runApp(LawHeatmapApp(repository: repository, settings: settings)); + runApp(ReclaimApp(repository: repository, settings: settings)); } /// Decide which repository to start with. @@ -28,8 +28,8 @@ Future _pickRepository(HubSettings settings) async { return const MockRepository(); } -class LawHeatmapApp extends StatelessWidget { - const LawHeatmapApp({ +class ReclaimApp extends StatelessWidget { + const ReclaimApp({ super.key, this.repository = const MockRepository(), this.settings, @@ -41,10 +41,10 @@ class LawHeatmapApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - title: 'F∆I Law-Heatmap', + title: 'Recl∆Im', debugShowCheckedModeBanner: false, - theme: LawHeatmapTheme.light(), - darkTheme: LawHeatmapTheme.dark(), + theme: ReclaimTheme.light(), + darkTheme: ReclaimTheme.dark(), themeMode: ThemeMode.dark, localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, diff --git a/app/lib/pages/about_page.dart b/app/lib/pages/about_page.dart index e7434f7..cff1356 100644 --- a/app/lib/pages/about_page.dart +++ b/app/lib/pages/about_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -import '../theme/lawheatmap_tokens.dart'; -import '../widgets/lawheatmap_card.dart'; +import '../theme/reclaim_tokens.dart'; +import '../widgets/reclaim_card.dart'; class AboutPage extends StatelessWidget { const AboutPage({super.key}); @@ -10,25 +10,25 @@ class AboutPage extends StatelessWidget { Widget build(BuildContext context) { final t = Theme.of(context).textTheme; return SingleChildScrollView( - padding: const EdgeInsets.all(LawHeatmapSpace.xl), + padding: const EdgeInsets.all(ReclaimSpace.xl), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Methodik & Quellen', style: t.displaySmall), - const SizedBox(height: LawHeatmapSpace.xs), + const SizedBox(height: ReclaimSpace.xs), Text( 'Wie das System bewertet, woran es sich messen lässt.', - style: t.bodyLarge?.copyWith(color: LawHeatmapColors.mute), + style: t.bodyLarge?.copyWith(color: ReclaimColors.mute), ), - const SizedBox(height: LawHeatmapSpace.lg), - LawHeatmapCard( + const SizedBox(height: ReclaimSpace.lg), + ReclaimCard( accent: true, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Drei nicht verhandelbare Sätze', style: t.headlineSmall), - const SizedBox(height: LawHeatmapSpace.md), + const SizedBox(height: ReclaimSpace.md), Text( '1. Wir bewerten Pflichten, nicht Gesetze.\n' '2. Jede Zahl trägt die Tier-Stufe ihres schwächsten ' @@ -40,13 +40,13 @@ class AboutPage extends StatelessWidget { ], ), ), - const SizedBox(height: LawHeatmapSpace.lg), - LawHeatmapCard( + const SizedBox(height: ReclaimSpace.lg), + ReclaimCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Methodische Vorbilder', style: t.headlineSmall), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.sm), _bullet(t, 'Standardkostenmodell (SKM) — Nationaler Normenkontrollrat. P × F × T × h.'), _bullet(t, @@ -62,13 +62,13 @@ class AboutPage extends StatelessWidget { ], ), ), - const SizedBox(height: LawHeatmapSpace.lg), - LawHeatmapCard( + const SizedBox(height: ReclaimSpace.lg), + ReclaimCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('4-Tier-Evidenz-Modell', style: t.headlineSmall), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.sm), _bullet(t, 'T1 — amtlich/peer-reviewed: NKR, DESTATIS, ifo, ZEW, BMWK, SVR, IfM Bonn.'), _bullet(t, @@ -80,13 +80,13 @@ class AboutPage extends StatelessWidget { ], ), ), - const SizedBox(height: LawHeatmapSpace.lg), - LawHeatmapCard( + const SizedBox(height: ReclaimSpace.lg), + ReclaimCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Plattform', style: t.headlineSmall), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.sm), Text( 'Ch∆In v0.16.0 — Vendor: F∆I = Flemming.AI. ' 'Hub. Module. Flow. Deterministisch, WASM-sandboxed, ' @@ -104,7 +104,7 @@ class AboutPage extends StatelessWidget { Widget _bullet(TextTheme t, String text) { return Padding( - padding: const EdgeInsets.only(bottom: LawHeatmapSpace.sm), + padding: const EdgeInsets.only(bottom: ReclaimSpace.sm), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -114,7 +114,7 @@ class AboutPage extends StatelessWidget { width: 5, height: 5, decoration: const BoxDecoration( - color: LawHeatmapColors.signal, + color: ReclaimColors.signal, shape: BoxShape.circle, ), ), diff --git a/app/lib/pages/heatmap_page.dart b/app/lib/pages/heatmap_page.dart index 37dc7f1..9fd69ce 100644 --- a/app/lib/pages/heatmap_page.dart +++ b/app/lib/pages/heatmap_page.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import '../data/models.dart'; import '../data/repository.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; import '../widgets/demo_banner.dart'; import '../widgets/heatmap_grid.dart'; -import '../widgets/lawheatmap_card.dart'; +import '../widgets/reclaim_card.dart'; import '../widgets/tier_badge.dart'; import 'norm_detail_page.dart'; @@ -35,7 +35,7 @@ class _HeatmapPageState extends State { const DemoBanner(), Expanded( child: Padding( - padding: const EdgeInsets.all(LawHeatmapSpace.xl), + padding: const EdgeInsets.all(ReclaimSpace.xl), child: FutureBuilder>( future: _future, builder: (context, snap) { @@ -48,18 +48,18 @@ class _HeatmapPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Heatmap', style: t.displaySmall), - const SizedBox(height: LawHeatmapSpace.xs), + const SizedBox(height: ReclaimSpace.xs), Text( 'X: jährliche Bürokratiekosten (€, log10). ' 'Y: Nutzen-Score 0–5. Punktgröße: Betroffenheit. ' 'Klick auf einen Punkt → Detail mit Pflichten + Quellen.', style: t.bodyLarge?.copyWith( - color: LawHeatmapColors.mute, + color: ReclaimColors.mute, ), ), - const SizedBox(height: LawHeatmapSpace.lg), + const SizedBox(height: ReclaimSpace.lg), Expanded( - child: LawHeatmapCard( + child: ReclaimCard( accent: true, expand: true, child: HeatmapGrid( @@ -77,10 +77,10 @@ class _HeatmapPageState extends State { ), ), ), - const SizedBox(height: LawHeatmapSpace.lg), + const SizedBox(height: ReclaimSpace.lg), Wrap( - spacing: LawHeatmapSpace.md, - runSpacing: LawHeatmapSpace.sm, + spacing: ReclaimSpace.md, + runSpacing: ReclaimSpace.sm, children: [ for (final e in items) InkWell( @@ -94,10 +94,10 @@ class _HeatmapPageState extends State { ), ); }, - child: LawHeatmapCard( + child: ReclaimCard( padding: const EdgeInsets.symmetric( - horizontal: LawHeatmapSpace.md, - vertical: LawHeatmapSpace.sm, + horizontal: ReclaimSpace.md, + vertical: ReclaimSpace.sm, ), child: Row( mainAxisSize: MainAxisSize.min, @@ -105,7 +105,7 @@ class _HeatmapPageState extends State { TierBadge( tier: e.tierLowest, compact: true), const SizedBox( - width: LawHeatmapSpace.sm), + width: ReclaimSpace.sm), Text( '${e.norm.jurabk} ${e.norm.paragraph}', style: t.labelLarge, diff --git a/app/lib/pages/hub_status_page.dart b/app/lib/pages/hub_status_page.dart index 8784ecb..906677f 100644 --- a/app/lib/pages/hub_status_page.dart +++ b/app/lib/pages/hub_status_page.dart @@ -3,9 +3,9 @@ import 'package:flutter/material.dart'; import '../data/hub_endpoint.dart'; import '../data/hub_repository.dart'; import '../data/repository.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; import '../widgets/hub_capabilities_card.dart'; -import '../widgets/lawheatmap_card.dart'; +import '../widgets/reclaim_card.dart'; /// Hub connection + settings. Read-only summary at the top, then /// an editable form for endpoint host/port/secure/token, then a @@ -109,18 +109,18 @@ class _HubStatusPageState extends State { final repo = widget.repository; final s = _settings; return SingleChildScrollView( - padding: const EdgeInsets.all(LawHeatmapSpace.xl), + padding: const EdgeInsets.all(ReclaimSpace.xl), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Ch∆In Hub', style: t.displaySmall), - const SizedBox(height: LawHeatmapSpace.xs), + const SizedBox(height: ReclaimSpace.xs), Text( 'Status der Verbindung und Konfiguration des lokalen Hubs.', - style: t.bodyLarge?.copyWith(color: LawHeatmapColors.mute), + style: t.bodyLarge?.copyWith(color: ReclaimColors.mute), ), - const SizedBox(height: LawHeatmapSpace.lg), - LawHeatmapCard( + const SizedBox(height: ReclaimSpace.lg), + ReclaimCard( accent: true, child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -142,23 +142,23 @@ class _HubStatusPageState extends State { ], ), ), - const SizedBox(height: LawHeatmapSpace.lg), - LawHeatmapCard( + const SizedBox(height: ReclaimSpace.lg), + ReclaimCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Verbindung konfigurieren', style: t.headlineSmall), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.sm), Text( '`chain serve` läuft standardmäßig auf ' '127.0.0.1:50051 ohne Auth. ' 'Bei aktiver Auth den Bearer-Token aus ' '~/.chain/hub-auth-token hier eintragen.', style: t.labelSmall - ?.copyWith(color: LawHeatmapColors.mute), + ?.copyWith(color: ReclaimColors.mute), ), - const SizedBox(height: LawHeatmapSpace.lg), + const SizedBox(height: ReclaimSpace.lg), Row(children: [ Expanded( flex: 3, @@ -170,7 +170,7 @@ class _HubStatusPageState extends State { ), ), ), - const SizedBox(width: LawHeatmapSpace.md), + const SizedBox(width: ReclaimSpace.md), Expanded( child: TextField( controller: _portCtl, @@ -182,7 +182,7 @@ class _HubStatusPageState extends State { ), ), ]), - const SizedBox(height: LawHeatmapSpace.md), + const SizedBox(height: ReclaimSpace.md), TextField( controller: _tokenCtl, decoration: const InputDecoration( @@ -190,23 +190,23 @@ class _HubStatusPageState extends State { ), obscureText: true, ), - const SizedBox(height: LawHeatmapSpace.md), + const SizedBox(height: ReclaimSpace.md), Row(children: [ Switch( value: _secure, onChanged: (v) => setState(() => _secure = v), ), - const SizedBox(width: LawHeatmapSpace.sm), + const SizedBox(width: ReclaimSpace.sm), const Text('TLS (https)'), - const SizedBox(width: LawHeatmapSpace.xl), + const SizedBox(width: ReclaimSpace.xl), Switch( value: _useHub, onChanged: (v) => setState(() => _useHub = v), ), - const SizedBox(width: LawHeatmapSpace.sm), + const SizedBox(width: ReclaimSpace.sm), const Text('Hub beim Start nutzen'), ]), - const SizedBox(height: LawHeatmapSpace.lg), + const SizedBox(height: ReclaimSpace.lg), Row(children: [ FilledButton.icon( onPressed: _probing ? null : _probe, @@ -221,7 +221,7 @@ class _HubStatusPageState extends State { : const Icon(Icons.bolt_outlined), label: const Text('Verbindung testen'), ), - const SizedBox(width: LawHeatmapSpace.md), + const SizedBox(width: ReclaimSpace.md), OutlinedButton.icon( onPressed: _save, icon: const Icon(Icons.save_outlined), @@ -229,24 +229,24 @@ class _HubStatusPageState extends State { ), ]), if (_probeMessage != null) ...[ - const SizedBox(height: LawHeatmapSpace.md), + const SizedBox(height: ReclaimSpace.md), Text(_probeMessage!, style: t.labelLarge?.copyWith( - color: LawHeatmapColors.signal, + color: ReclaimColors.signal, )), ], ], ), ), - const SizedBox(height: LawHeatmapSpace.lg), + const SizedBox(height: ReclaimSpace.lg), HubCapabilitiesCard(repository: repo), - const SizedBox(height: LawHeatmapSpace.lg), - LawHeatmapCard( + const SizedBox(height: ReclaimSpace.lg), + ReclaimCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Geplanter Live-Flow', style: t.headlineSmall), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.sm), Text( '1. `chain serve` auf localhost:50051 starten.\n' '2. Module installieren (`chain install`).\n' @@ -261,7 +261,7 @@ class _HubStatusPageState extends State { 'Evaluation-Objekte übersetzt.', style: t.bodyLarge?.copyWith( height: 1.6, - fontFamily: LawHeatmapTypography.mono, + fontFamily: ReclaimTypography.mono, fontSize: 12, ), ), @@ -282,12 +282,12 @@ class _HubStatusPageState extends State { width: 200, child: Text(label, style: t.labelLarge - ?.copyWith(color: LawHeatmapColors.mute)), + ?.copyWith(color: ReclaimColors.mute)), ), Expanded( child: Text(value, style: t.bodyLarge - ?.copyWith(fontFamily: LawHeatmapTypography.mono)), + ?.copyWith(fontFamily: ReclaimTypography.mono)), ), ], ), diff --git a/app/lib/pages/landing_page.dart b/app/lib/pages/landing_page.dart index a10745d..0f19bac 100644 --- a/app/lib/pages/landing_page.dart +++ b/app/lib/pages/landing_page.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import '../data/repository.dart'; -import '../theme/lawheatmap_theme.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_theme.dart'; +import '../theme/reclaim_tokens.dart'; import '../widgets/delta_mark.dart'; import 'shell_page.dart'; @@ -23,28 +23,28 @@ class LandingPage extends StatelessWidget { constraints: const BoxConstraints(maxWidth: 720), child: Padding( padding: const EdgeInsets.symmetric( - horizontal: LawHeatmapSpace.xxl, - vertical: LawHeatmapSpace.xxxl, + horizontal: ReclaimSpace.xxl, + vertical: ReclaimSpace.xxxl, ), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ const DeltaMark(size: 96), - const SizedBox(height: LawHeatmapSpace.xxl), - Text('F∆I Law-Heatmap', style: t.displaySmall), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.xxl), + Text('Recl∆Im', style: t.displaySmall), + const SizedBox(height: ReclaimSpace.sm), Text( 'Pflicht-basierte Wirkungsanalyse von Rechtsnormen — ' 'auf Ch∆In, mit Quellen-Audit by construction.', style: t.bodyLarge - ?.copyWith(color: LawHeatmapColors.mute), + ?.copyWith(color: ReclaimColors.mute), ), - const SizedBox(height: LawHeatmapSpace.xxl), + const SizedBox(height: ReclaimSpace.xxl), Wrap( crossAxisAlignment: WrapCrossAlignment.center, - spacing: LawHeatmapSpace.md, - runSpacing: LawHeatmapSpace.sm, + spacing: ReclaimSpace.md, + runSpacing: ReclaimSpace.sm, children: [ FilledButton.icon( onPressed: () { @@ -61,18 +61,18 @@ class LandingPage extends StatelessWidget { Text( 'Demo: 5 Pilot-Normen, ohne Hub-Verbindung', style: t.labelSmall?.copyWith( - color: LawHeatmapColors.mute, + color: ReclaimColors.mute, ), ), ], ), - const SizedBox(height: LawHeatmapSpace.xl), + const SizedBox(height: ReclaimSpace.xl), Text( 'v0.1.0 · Phase 0 · Mock-Modus · ' 'Live-Hub-Anbindung folgt in Woche 1', - style: LawHeatmapTheme.mono( + style: ReclaimTheme.mono( t.labelSmall ?? const TextStyle(), - ).copyWith(color: LawHeatmapColors.mute), + ).copyWith(color: ReclaimColors.mute), ), ], ), diff --git a/app/lib/pages/norms_list_page.dart b/app/lib/pages/norms_list_page.dart index 9f0d9b2..189a1fb 100644 --- a/app/lib/pages/norms_list_page.dart +++ b/app/lib/pages/norms_list_page.dart @@ -2,9 +2,9 @@ import 'package:flutter/material.dart'; import '../data/models.dart'; import '../data/repository.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; import '../widgets/demo_banner.dart'; -import '../widgets/lawheatmap_card.dart'; +import '../widgets/reclaim_card.dart'; import '../widgets/tier_badge.dart'; import 'norm_detail_page.dart'; @@ -21,20 +21,20 @@ class NormsListPage extends StatelessWidget { const DemoBanner(), Expanded( child: SingleChildScrollView( - padding: const EdgeInsets.all(LawHeatmapSpace.xl), + padding: const EdgeInsets.all(ReclaimSpace.xl), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Normen-Pilotkorpus', style: t.displaySmall), - const SizedBox(height: LawHeatmapSpace.xs), + const SizedBox(height: ReclaimSpace.xs), Text( '5 Normen für den vertikalen Durchstich. ' 'Korpus erweiterbar in Phase 1.', style: t.bodyLarge?.copyWith( - color: LawHeatmapColors.mute, + color: ReclaimColors.mute, ), ), - const SizedBox(height: LawHeatmapSpace.lg), + const SizedBox(height: ReclaimSpace.lg), FutureBuilder>( future: repository.list(), builder: (context, snap) { @@ -47,7 +47,7 @@ class NormsListPage extends StatelessWidget { for (final e in snap.data!) Padding( padding: const EdgeInsets.only( - bottom: LawHeatmapSpace.md), + bottom: ReclaimSpace.md), child: _NormRow( evaluation: e, repository: repository, @@ -86,7 +86,7 @@ class _NormRow extends StatelessWidget { ), ); }, - child: LawHeatmapCard( + child: ReclaimCard( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -103,14 +103,14 @@ class _NormRow extends StatelessWidget { Text( evaluation.norm.eli, style: t.labelSmall?.copyWith( - fontFamily: LawHeatmapTypography.mono, - color: LawHeatmapColors.mute, + fontFamily: ReclaimTypography.mono, + color: ReclaimColors.mute, ), ), ], ), ), - const SizedBox(width: LawHeatmapSpace.lg), + const SizedBox(width: ReclaimSpace.lg), Expanded( child: _MetricColumn( label: 'Schaden / Jahr', @@ -130,7 +130,7 @@ class _NormRow extends StatelessWidget { value: _kmu(evaluation.affectedCount), ), ), - const SizedBox(width: LawHeatmapSpace.md), + const SizedBox(width: ReclaimSpace.md), TierBadge(tier: evaluation.tierLowest), ], ), @@ -166,7 +166,7 @@ class _MetricColumn extends StatelessWidget { children: [ Text( label, - style: t.labelSmall?.copyWith(color: LawHeatmapColors.mute), + style: t.labelSmall?.copyWith(color: ReclaimColors.mute), ), const SizedBox(height: 2), Text(value, style: t.titleMedium), diff --git a/app/lib/pages/shell_page.dart b/app/lib/pages/shell_page.dart index 75dc952..fcbebde 100644 --- a/app/lib/pages/shell_page.dart +++ b/app/lib/pages/shell_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import '../data/repository.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; import '../widgets/delta_mark.dart'; import 'about_page.dart'; import 'heatmap_page.dart'; @@ -42,18 +42,18 @@ class _ShellPageState extends State { onDestinationSelected: (i) => setState(() => _index = i), leading: Padding( padding: const EdgeInsets.symmetric( - vertical: LawHeatmapSpace.lg, - horizontal: LawHeatmapSpace.md, + vertical: ReclaimSpace.lg, + horizontal: ReclaimSpace.md, ), child: Column( children: [ const DeltaMark(size: 36), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.sm), Text( 'F∆I', style: t.labelLarge?.copyWith( letterSpacing: 2, - color: LawHeatmapColors.signal, + color: ReclaimColors.signal, ), ), ], diff --git a/app/lib/theme/lawheatmap_theme.dart b/app/lib/theme/reclaim_theme.dart similarity index 73% rename from app/lib/theme/lawheatmap_theme.dart rename to app/lib/theme/reclaim_theme.dart index c894707..012a9b2 100644 --- a/app/lib/theme/lawheatmap_theme.dart +++ b/app/lib/theme/reclaim_theme.dart @@ -1,35 +1,35 @@ import 'package:flutter/material.dart'; -import 'lawheatmap_tokens.dart'; +import 'reclaim_tokens.dart'; -/// ThemeData assembly for the F∆I Law-Heatmap client. +/// ThemeData assembly for the F∆I Recl∆Im client. /// /// Dark mode is the default (consistent with fai_web's /// `color-scheme: dark`). Light mode falls back to the paper /// palette for printing/screenshot work. -class LawHeatmapTheme { - LawHeatmapTheme._(); +class ReclaimTheme { + ReclaimTheme._(); static ThemeData dark() => _build(Brightness.dark); static ThemeData light() => _build(Brightness.light); static ThemeData _build(Brightness brightness) { final isDark = brightness == Brightness.dark; - final canvas = isDark ? LawHeatmapColors.ink : LawHeatmapColors.paper; + final canvas = isDark ? ReclaimColors.ink : ReclaimColors.paper; final surface = - isDark ? LawHeatmapColors.inkRaised : LawHeatmapColors.paperRaised; + isDark ? ReclaimColors.inkRaised : ReclaimColors.paperRaised; final onSurface = isDark ? const Color(0xFFE9E7E2) : const Color(0xFF1A1B1E); final colorScheme = ColorScheme( brightness: brightness, - primary: LawHeatmapColors.signal, - onPrimary: LawHeatmapColors.ink, - secondary: LawHeatmapColors.mute, + primary: ReclaimColors.signal, + onPrimary: ReclaimColors.ink, + secondary: ReclaimColors.mute, onSecondary: onSurface, error: const Color(0xFFD8723A), - onError: LawHeatmapColors.ink, + onError: ReclaimColors.ink, surface: surface, onSurface: onSurface, ); @@ -42,33 +42,33 @@ class LawHeatmapTheme { colorScheme: colorScheme, scaffoldBackgroundColor: canvas, canvasColor: canvas, - fontFamily: LawHeatmapTypography.body, + fontFamily: ReclaimTypography.body, textTheme: textTheme, cardTheme: CardThemeData( color: surface, elevation: 0, margin: EdgeInsets.zero, shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(LawHeatmapRadius.md), + borderRadius: BorderRadius.all(ReclaimRadius.md), side: BorderSide(color: Color(0x24FFFFFF)), ), ), dividerTheme: DividerThemeData( - color: onSurface.withValues(alpha: LawHeatmapColors.hairlineDarkOpacity), + color: onSurface.withValues(alpha: ReclaimColors.hairlineDarkOpacity), thickness: 1, space: 1, ), filledButtonTheme: FilledButtonThemeData( style: FilledButton.styleFrom( - backgroundColor: LawHeatmapColors.signal, - foregroundColor: LawHeatmapColors.ink, + backgroundColor: ReclaimColors.signal, + foregroundColor: ReclaimColors.ink, shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(LawHeatmapRadius.sm), + borderRadius: BorderRadius.all(ReclaimRadius.sm), ), textStyle: textTheme.labelLarge, padding: const EdgeInsets.symmetric( - horizontal: LawHeatmapSpace.lg, - vertical: LawHeatmapSpace.md, + horizontal: ReclaimSpace.lg, + vertical: ReclaimSpace.md, ), ), ), @@ -76,8 +76,8 @@ class LawHeatmapTheme { } static TextTheme _textTheme(Color onSurface) { - const display = LawHeatmapTypography.display; - const body = LawHeatmapTypography.body; + const display = ReclaimTypography.display; + const body = ReclaimTypography.body; return TextTheme( displaySmall: TextStyle( fontFamily: display, @@ -123,5 +123,5 @@ class LawHeatmapTheme { /// Convenience: JetBrains-Mono variant of an existing style for /// technical content (ELI/CELEX, SHA-256, audit-event IDs). static TextStyle mono(TextStyle base) => - base.copyWith(fontFamily: LawHeatmapTypography.mono); + base.copyWith(fontFamily: ReclaimTypography.mono); } diff --git a/app/lib/theme/lawheatmap_tokens.dart b/app/lib/theme/reclaim_tokens.dart similarity index 88% rename from app/lib/theme/lawheatmap_tokens.dart rename to app/lib/theme/reclaim_tokens.dart index a473a3e..654bde6 100644 --- a/app/lib/theme/lawheatmap_tokens.dart +++ b/app/lib/theme/reclaim_tokens.dart @@ -1,14 +1,14 @@ import 'package:flutter/material.dart'; -/// Visual tokens for the F∆I Law-Heatmap client, sourced from the +/// Visual tokens for the F∆I Recl∆Im client, sourced from the /// fai_web brand palette (see fai_web/src/styles/global.css:14-20). /// /// Unlike `fai_chain_studio`'s `ChainColors` (Tailwind sky-400 — /// dev-tool look), this palette matches the public-facing brand: /// ink/paper with a petrol "signal" accent that doubles as the eye /// of the `∆` mark. -class LawHeatmapColors { - LawHeatmapColors._(); +class ReclaimColors { + ReclaimColors._(); // Core palette (fai_web/src/styles/global.css) static const ink = Color(0xFF08090A); @@ -40,8 +40,8 @@ class LawHeatmapColors { /// Spacing scale — 4/8/12/16/24/32/48 multiples, matching /// `ChainSpace` from `fai_chain_studio/lib/theme/tokens.dart`. -class LawHeatmapSpace { - LawHeatmapSpace._(); +class ReclaimSpace { + ReclaimSpace._(); static const xs = 4.0; static const sm = 8.0; @@ -52,15 +52,15 @@ class LawHeatmapSpace { static const xxxl = 48.0; } -class LawHeatmapRadius { - LawHeatmapRadius._(); +class ReclaimRadius { + ReclaimRadius._(); static const sm = Radius.circular(6); static const md = Radius.circular(10); } -class LawHeatmapTypography { - LawHeatmapTypography._(); +class ReclaimTypography { + ReclaimTypography._(); static const display = 'SpaceGroteskVariable'; static const body = 'InterVariable'; diff --git a/app/lib/widgets/delta_mark.dart b/app/lib/widgets/delta_mark.dart index 30db44d..fd921cb 100644 --- a/app/lib/widgets/delta_mark.dart +++ b/app/lib/widgets/delta_mark.dart @@ -2,7 +2,7 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; /// The F∆I / Ch∆In brand mark: an upward triangle (the `∆`) with /// a petrol "eye" at the centre. Geometry mirrors fai_web's @@ -89,7 +89,7 @@ class _DeltaPainter extends CustomPainter { // Eye — petrol fill, centred on the triangle's centroid. final eyeCentre = Offset(w / 2, inset + (h - 2 * inset) * 2 / 3); final eyeR = w * 0.06 * pulse; - final eye = Paint()..color = LawHeatmapColors.signal; + final eye = Paint()..color = ReclaimColors.signal; canvas.drawCircle(eyeCentre, eyeR, eye); } diff --git a/app/lib/widgets/demo_banner.dart b/app/lib/widgets/demo_banner.dart index b697bc4..0d41fc0 100644 --- a/app/lib/widgets/demo_banner.dart +++ b/app/lib/widgets/demo_banner.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; /// Permanent banner shown above all data screens in mock mode. /// Carries the political-defensibility caveat: this is demo data, @@ -14,29 +14,29 @@ class DemoBanner extends StatelessWidget { return Container( width: double.infinity, padding: const EdgeInsets.symmetric( - horizontal: LawHeatmapSpace.lg, - vertical: LawHeatmapSpace.sm, + horizontal: ReclaimSpace.lg, + vertical: ReclaimSpace.sm, ), decoration: BoxDecoration( - color: LawHeatmapColors.tierT4.withValues(alpha: 0.12), + color: ReclaimColors.tierT4.withValues(alpha: 0.12), border: Border( bottom: BorderSide( - color: LawHeatmapColors.tierT4.withValues(alpha: 0.55), + color: ReclaimColors.tierT4.withValues(alpha: 0.55), ), ), ), child: Row( children: [ const Icon(Icons.science_outlined, - size: 18, color: LawHeatmapColors.tierT4), - const SizedBox(width: LawHeatmapSpace.sm), + size: 18, color: ReclaimColors.tierT4), + const SizedBox(width: ReclaimSpace.sm), Expanded( child: Text( '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: LawHeatmapColors.tierT4, + color: ReclaimColors.tierT4, ), ), ), diff --git a/app/lib/widgets/evidence_sidebar.dart b/app/lib/widgets/evidence_sidebar.dart index 070f313..ab4aa7a 100644 --- a/app/lib/widgets/evidence_sidebar.dart +++ b/app/lib/widgets/evidence_sidebar.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import '../data/models.dart'; -import '../theme/lawheatmap_tokens.dart'; -import 'lawheatmap_card.dart'; +import '../theme/reclaim_tokens.dart'; +import 'reclaim_card.dart'; import 'source_chip.dart'; /// Sidebar listing the citable sources behind an evaluation. @@ -16,39 +16,39 @@ class EvidenceSidebar extends StatelessWidget { @override Widget build(BuildContext context) { final t = Theme.of(context).textTheme; - return LawHeatmapCard( + return ReclaimCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Quellen', style: t.headlineSmall), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.sm), Text( 'Jede Zahl trägt die Tier-Stufe ihres schwächsten ' 'Bestandteils (Regel der niedrigsten Stufe, §6.7).', - style: t.labelSmall?.copyWith(color: LawHeatmapColors.mute), + style: t.labelSmall?.copyWith(color: ReclaimColors.mute), ), - const SizedBox(height: LawHeatmapSpace.lg), + const SizedBox(height: ReclaimSpace.lg), for (final s in evaluation.sources) SourceChip(source: s), - const Divider(height: LawHeatmapSpace.xl), + const Divider(height: ReclaimSpace.xl), Text('Audit-Event', style: t.labelLarge), const SizedBox(height: 4), SelectableText( evaluation.auditEventId, style: t.labelSmall?.copyWith( - fontFamily: LawHeatmapTypography.mono, - color: LawHeatmapColors.mute, + fontFamily: ReclaimTypography.mono, + color: ReclaimColors.mute, ), ), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.sm), Text( 'Quell-SHA-256:', - style: t.labelSmall?.copyWith(color: LawHeatmapColors.mute), + style: t.labelSmall?.copyWith(color: ReclaimColors.mute), ), SelectableText( evaluation.norm.sourceSha256, style: t.labelSmall?.copyWith( - fontFamily: LawHeatmapTypography.mono, - color: LawHeatmapColors.mute, + fontFamily: ReclaimTypography.mono, + color: ReclaimColors.mute, fontSize: 10, ), ), diff --git a/app/lib/widgets/heatmap_grid.dart b/app/lib/widgets/heatmap_grid.dart index bf2fa41..3abb1a8 100644 --- a/app/lib/widgets/heatmap_grid.dart +++ b/app/lib/widgets/heatmap_grid.dart @@ -3,7 +3,7 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; import '../data/models.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; /// 2D scatter heatmap — x: Schaden (€/Jahr, log-scaled), /// y: Nutzen (0–5), point area: Betroffenheit (sqrt-scaled). @@ -121,7 +121,7 @@ class _HeatmapPainter extends CustomPainter { void paint(Canvas canvas, Size size) { final layout = _Layout(size); final onSurface = theme.colorScheme.onSurface; - const mute = LawHeatmapColors.mute; + const mute = ReclaimColors.mute; // Plot frame. final frame = Paint() @@ -163,7 +163,7 @@ class _HeatmapPainter extends CustomPainter { const axisStyle = TextStyle( color: mute, fontSize: 10, - fontFamily: LawHeatmapTypography.body, + fontFamily: ReclaimTypography.body, ); _drawText( canvas, @@ -205,8 +205,8 @@ class _HeatmapPainter extends CustomPainter { final r = layout.radius(e); final hot = e.skmEurPerYear > 50000000; final color = Color.lerp( - LawHeatmapColors.benefitSaturated, - LawHeatmapColors.harmWarm, + ReclaimColors.benefitSaturated, + ReclaimColors.harmWarm, hot ? 0.5 : 0.0, )!; final body = Paint()..color = color.withValues(alpha: 0.7); @@ -224,7 +224,7 @@ class _HeatmapPainter extends CustomPainter { TextStyle( color: onSurface, fontSize: 11, - fontFamily: LawHeatmapTypography.body, + fontFamily: ReclaimTypography.body, fontWeight: i == hoverIndex ? FontWeight.w600 : FontWeight.w400, ), ); @@ -240,8 +240,8 @@ class _HeatmapPainter extends CustomPainter { ..color = theme.colorScheme.surface.withValues(alpha: 0.92); final boxBorder = Paint() ..style = PaintingStyle.stroke - ..color = LawHeatmapColors.signal.withValues(alpha: 0.6); - final rrect = RRect.fromRectAndRadius(box, LawHeatmapRadius.sm); + ..color = ReclaimColors.signal.withValues(alpha: 0.6); + final rrect = RRect.fromRectAndRadius(box, ReclaimRadius.sm); canvas.drawRRect(rrect, boxPaint); canvas.drawRRect(rrect, boxBorder); _drawText( @@ -252,7 +252,7 @@ class _HeatmapPainter extends CustomPainter { color: onSurface, fontSize: 12, fontWeight: FontWeight.w600, - fontFamily: LawHeatmapTypography.body, + fontFamily: ReclaimTypography.body, ), ); _drawText( @@ -262,7 +262,7 @@ class _HeatmapPainter extends CustomPainter { const TextStyle( color: mute, fontSize: 11, - fontFamily: LawHeatmapTypography.body, + fontFamily: ReclaimTypography.body, ), ); _drawText( @@ -272,7 +272,7 @@ class _HeatmapPainter extends CustomPainter { const TextStyle( color: mute, fontSize: 11, - fontFamily: LawHeatmapTypography.body, + fontFamily: ReclaimTypography.body, ), ); } diff --git a/app/lib/widgets/hub_capabilities_card.dart b/app/lib/widgets/hub_capabilities_card.dart index 42d644e..3ed4d51 100644 --- a/app/lib/widgets/hub_capabilities_card.dart +++ b/app/lib/widgets/hub_capabilities_card.dart @@ -3,8 +3,8 @@ import 'package:flutter/material.dart'; import '../data/hub_repository.dart'; import '../data/repository.dart'; -import '../theme/lawheatmap_tokens.dart'; -import 'lawheatmap_card.dart'; +import '../theme/reclaim_tokens.dart'; +import 'reclaim_card.dart'; /// Lists the capabilities the connected hub has installed. /// Empty / explanatory state when the active repository is not @@ -39,7 +39,7 @@ class _HubCapabilitiesCardState extends State { final repo = widget.repository; final liveHub = repo is HubRepository && repo.isHealthy; - return LawHeatmapCard( + return ReclaimCard( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -53,13 +53,13 @@ class _HubCapabilitiesCardState extends State { icon: const Icon(Icons.refresh), ), ]), - const SizedBox(height: LawHeatmapSpace.sm), + const SizedBox(height: ReclaimSpace.sm), if (!liveHub) Text( 'Sichtbar sobald die App im Hub-Modus startet und ' 'der Hub erreichbar ist (siehe Verbindung oben).', style: t.labelSmall?.copyWith( - color: LawHeatmapColors.mute, + color: ReclaimColors.mute, ), ) else @@ -68,14 +68,14 @@ class _HubCapabilitiesCardState extends State { builder: (context, snap) { if (snap.connectionState == ConnectionState.waiting) { return const Padding( - padding: EdgeInsets.all(LawHeatmapSpace.md), + padding: EdgeInsets.all(ReclaimSpace.md), child: CircularProgressIndicator(), ); } if (snap.hasError) { return Text('Fehler: ${snap.error}', style: t.labelLarge - ?.copyWith(color: LawHeatmapColors.harmWarm)); + ?.copyWith(color: ReclaimColors.harmWarm)); } final items = snap.data ?? const []; if (items.isEmpty) { @@ -83,7 +83,7 @@ class _HubCapabilitiesCardState extends State { 'Hub hat noch keine Capabilities installiert. ' 'Mit `chain install ` hinzufügen.', style: t.bodyLarge?.copyWith( - color: LawHeatmapColors.mute, + color: ReclaimColors.mute, ), ); } @@ -101,7 +101,7 @@ class _HubCapabilitiesCardState extends State { child: Text( '${c.capability}@${c.version}', style: t.bodyLarge?.copyWith( - fontFamily: LawHeatmapTypography.mono, + fontFamily: ReclaimTypography.mono, ), ), ), @@ -110,7 +110,7 @@ class _HubCapabilitiesCardState extends State { '${c.moduleName} ${c.moduleVersion}' '${c.kind.isEmpty ? "" : " · ${c.kind}"}', style: t.labelSmall?.copyWith( - color: LawHeatmapColors.mute, + color: ReclaimColors.mute, ), ), ), diff --git a/app/lib/widgets/lawheatmap_card.dart b/app/lib/widgets/reclaim_card.dart similarity index 83% rename from app/lib/widgets/lawheatmap_card.dart rename to app/lib/widgets/reclaim_card.dart index 8a84701..891956f 100644 --- a/app/lib/widgets/lawheatmap_card.dart +++ b/app/lib/widgets/reclaim_card.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; /// Surface container — visual equivalent of fai_chain_studio's /// `ChainCard`, retuned to the fai_web palette. -class LawHeatmapCard extends StatelessWidget { - const LawHeatmapCard({ +class ReclaimCard extends StatelessWidget { + const ReclaimCard({ super.key, required this.child, this.padding = - const EdgeInsets.all(LawHeatmapSpace.lg), + const EdgeInsets.all(ReclaimSpace.lg), this.accent = false, this.expand = false, }); @@ -39,9 +39,9 @@ class LawHeatmapCard extends StatelessWidget { Container( height: 2, decoration: const BoxDecoration( - color: LawHeatmapColors.signal, + color: ReclaimColors.signal, borderRadius: BorderRadius.vertical( - top: LawHeatmapRadius.md, + top: ReclaimRadius.md, ), ), ), diff --git a/app/lib/widgets/source_chip.dart b/app/lib/widgets/source_chip.dart index ca81fa7..fdd16c0 100644 --- a/app/lib/widgets/source_chip.dart +++ b/app/lib/widgets/source_chip.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import '../data/models.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; import 'tier_badge.dart'; /// A citable source line: tier badge + label + (planned) link. @@ -16,7 +16,7 @@ class SourceChip extends StatelessWidget { Widget build(BuildContext context) { final t = Theme.of(context).textTheme; return Padding( - padding: const EdgeInsets.only(bottom: LawHeatmapSpace.sm), + padding: const EdgeInsets.only(bottom: ReclaimSpace.sm), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -24,7 +24,7 @@ class SourceChip extends StatelessWidget { padding: const EdgeInsets.only(top: 2), child: TierBadge(tier: source.tier, compact: true), ), - const SizedBox(width: LawHeatmapSpace.sm), + const SizedBox(width: ReclaimSpace.sm), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -33,14 +33,14 @@ class SourceChip extends StatelessWidget { Text( source.url, style: t.labelSmall?.copyWith( - color: LawHeatmapColors.mute, + color: ReclaimColors.mute, ), ), if (source.note != null) Text( source.note!, style: t.labelSmall?.copyWith( - color: LawHeatmapColors.mute, + color: ReclaimColors.mute, fontStyle: FontStyle.italic, ), ), diff --git a/app/lib/widgets/tier_badge.dart b/app/lib/widgets/tier_badge.dart index b194a6b..282eed6 100644 --- a/app/lib/widgets/tier_badge.dart +++ b/app/lib/widgets/tier_badge.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import '../data/models.dart'; -import '../theme/lawheatmap_tokens.dart'; +import '../theme/reclaim_tokens.dart'; /// Tier badge — surfaces the lowest evidence tier in a composed /// value. Every figure in the app carries one of these next to it. @@ -15,22 +15,22 @@ class TierBadge extends StatelessWidget { Widget build(BuildContext context) { final t = Theme.of(context).textTheme; final color = switch (tier) { - EvidenceTier.t1 => LawHeatmapColors.tierT1, - EvidenceTier.t2 => LawHeatmapColors.tierT2, - EvidenceTier.t3 => LawHeatmapColors.tierT3, - EvidenceTier.t4 => LawHeatmapColors.tierT4, + EvidenceTier.t1 => ReclaimColors.tierT1, + EvidenceTier.t2 => ReclaimColors.tierT2, + EvidenceTier.t3 => ReclaimColors.tierT3, + EvidenceTier.t4 => ReclaimColors.tierT4, }; return Tooltip( message: '${tier.short} — ${tier.description}', child: Container( padding: EdgeInsets.symmetric( - horizontal: compact ? 6 : LawHeatmapSpace.sm, + horizontal: compact ? 6 : ReclaimSpace.sm, vertical: compact ? 2 : 4, ), decoration: BoxDecoration( color: color.withValues(alpha: 0.18), border: Border.all(color: color.withValues(alpha: 0.55)), - borderRadius: const BorderRadius.all(LawHeatmapRadius.sm), + borderRadius: const BorderRadius.all(ReclaimRadius.sm), ), child: Row( mainAxisSize: MainAxisSize.min, diff --git a/app/macos/Runner.xcodeproj/project.pbxproj b/app/macos/Runner.xcodeproj/project.pbxproj index 07f152c..00d1a7d 100644 --- a/app/macos/Runner.xcodeproj/project.pbxproj +++ b/app/macos/Runner.xcodeproj/project.pbxproj @@ -65,7 +65,7 @@ 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* lawheatmap_app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "lawheatmap_app.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* reclaim_app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "reclaim_app.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -134,7 +134,7 @@ 33CC10EE2044A3C60003C045 /* Products */ = { isa = PBXGroup; children = ( - 33CC10ED2044A3C60003C045 /* lawheatmap_app.app */, + 33CC10ED2044A3C60003C045 /* reclaim_app.app */, 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, ); name = Products; @@ -224,7 +224,7 @@ 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, ); productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* lawheatmap_app.app */; + productReference = 33CC10ED2044A3C60003C045 /* reclaim_app.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -395,10 +395,10 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.lawheatmapApp.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.reclaim.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/lawheatmap_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/lawheatmap_app"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/reclaim_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/reclaim_app"; }; name = Debug; }; @@ -409,10 +409,10 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.lawheatmapApp.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.reclaim.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/lawheatmap_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/lawheatmap_app"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/reclaim_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/reclaim_app"; }; name = Release; }; @@ -423,10 +423,10 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.lawheatmapApp.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.reclaim.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/lawheatmap_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/lawheatmap_app"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/reclaim_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/reclaim_app"; }; name = Profile; }; diff --git a/app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 45c3a4d..a74a1e8 100644 --- a/app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -15,7 +15,7 @@ @@ -33,7 +33,7 @@ @@ -49,7 +49,7 @@ @@ -84,7 +84,7 @@ @@ -101,7 +101,7 @@ diff --git a/app/macos/Runner/Configs/AppInfo.xcconfig b/app/macos/Runner/Configs/AppInfo.xcconfig index 3ad4d22..51f8e2b 100644 --- a/app/macos/Runner/Configs/AppInfo.xcconfig +++ b/app/macos/Runner/Configs/AppInfo.xcconfig @@ -5,10 +5,10 @@ // 'flutter create' template. // The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = lawheatmap_app +PRODUCT_NAME = reclaim_app // The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.lawheatmapApp +PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.reclaim // The copyright displayed in application information PRODUCT_COPYRIGHT = Copyright © 2026 ai.flemming. All rights reserved. diff --git a/app/pubspec.lock b/app/pubspec.lock index 5cb87e4..c077d58 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -409,6 +409,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32 + url: "https://pub.dev" + source: hosted + version: "6.3.32" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + url: "https://pub.dev" + source: hosted + version: "6.4.1" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + url: "https://pub.dev" + source: hosted + version: "3.2.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + url: "https://pub.dev" + source: hosted + version: "3.2.5" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34" + url: "https://pub.dev" + source: hosted + version: "2.4.3" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + url: "https://pub.dev" + source: hosted + version: "3.1.5" vector_math: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 0eb45b5..c43960b 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -1,5 +1,5 @@ -name: lawheatmap_app -description: F∆I Law-Heatmap — Flutter client for the Ch∆In-based law-bureaucracy heatmap. +name: reclaim_app +description: Recl∆Im — Flutter client for the Ch∆In-based duty-level reform-mapping platform (F∆I). publish_to: 'none' version: 0.1.0+1 @@ -14,6 +14,7 @@ dependencies: sdk: flutter intl: ^0.20.2 shared_preferences: ^2.3.0 + url_launcher: ^6.3.0 # Ch∆In gRPC wire — sibling-path dep, same pattern as # fai_chain_studio. Adapt the chain_client_sdk_dart relative diff --git a/app/test/widget_test.dart b/app/test/widget_test.dart index 873b29f..eb83a95 100644 --- a/app/test/widget_test.dart +++ b/app/test/widget_test.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:lawheatmap_app/main.dart'; +import 'package:reclaim_app/main.dart'; void main() { // Generous surface so NavigationRail + Heatmap fit without @@ -18,9 +18,9 @@ void main() { testWidgets('Landing renders brand mark + CTA', (WidgetTester tester) async { await tester.binding.setSurfaceSize(surfaceSize); - await tester.pumpWidget(const LawHeatmapApp()); + await tester.pumpWidget(const ReclaimApp()); await tester.pump(); - expect(find.text('F∆I Law-Heatmap'), findsOneWidget); + expect(find.text('Recl∆Im'), findsOneWidget); expect( find.widgetWithText(FilledButton, 'App öffnen (Demo-Modus)'), findsOneWidget, @@ -31,7 +31,7 @@ void main() { testWidgets('Tapping CTA reaches the shell and shows the heatmap', (WidgetTester tester) async { await tester.binding.setSurfaceSize(surfaceSize); - await tester.pumpWidget(const LawHeatmapApp()); + await tester.pumpWidget(const ReclaimApp()); await tester.pump(); await tester.tap( find.widgetWithText(FilledButton, 'App öffnen (Demo-Modus)'), diff --git a/flows/durchstich-gewo-14.yaml b/flows/durchstich-gewo-14.yaml index d7eb63f..5b2162d 100644 --- a/flows/durchstich-gewo-14.yaml +++ b/flows/durchstich-gewo-14.yaml @@ -122,7 +122,7 @@ steps: - id: review use: system.approval@^0 with: - title: "F∆I Law-Heatmap — Review ${{ normalize.norm.eli }}" + title: "Recl∆Im (F∆I) — Review ${{ normalize.norm.eli }}" payload: norm: ${{ normalize.norm }} skm: ${{ skm.report }}