diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 3b955ba..e9f1e81 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -6,7 +6,6 @@ "navWelcome": "Willkommen", "welcomeHeroTitle": "F∆I Platform", "welcomeHeroSubtitle": "Deterministische Workflow-Engine für KI-gestützte Dokumentenverarbeitung in regulierten Umgebungen.", - "welcomePillarsHeader": "WIE ES ZUSAMMENPASST", "welcomePillarHubTitle": "Hub", "welcomePillarHubBody": "Ein Rust-Binary, das Module lädt und Flows ausführt. SQLite für den State. Kein Docker, kein Message-Broker, keine Hintergrunddienste, die gepflegt werden müssen.", "welcomePillarModuleTitle": "Modul", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 6b9ab19..7ee1b66 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -7,7 +7,6 @@ "navWelcome": "Welcome", "welcomeHeroTitle": "F∆I Platform", "welcomeHeroSubtitle": "Deterministic workflow engine for AI-assisted document processing in regulated environments.", - "welcomePillarsHeader": "HOW IT FITS TOGETHER", "welcomePillarHubTitle": "Hub", "welcomePillarHubBody": "One Rust binary that loads modules and runs flows. SQLite for state. No Docker, no message broker, no background services to babysit.", "welcomePillarModuleTitle": "Module", diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 6406d90..2692df9 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -122,12 +122,6 @@ abstract class AppLocalizations { /// **'Deterministic workflow engine for AI-assisted document processing in regulated environments.'** String get welcomeHeroSubtitle; - /// No description provided for @welcomePillarsHeader. - /// - /// In en, this message translates to: - /// **'HOW IT FITS TOGETHER'** - String get welcomePillarsHeader; - /// No description provided for @welcomePillarHubTitle. /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart index 24c1976..4f23805 100644 --- a/lib/l10n/app_localizations_de.dart +++ b/lib/l10n/app_localizations_de.dart @@ -21,9 +21,6 @@ class AppLocalizationsDe extends AppLocalizations { String get welcomeHeroSubtitle => 'Deterministische Workflow-Engine für KI-gestützte Dokumentenverarbeitung in regulierten Umgebungen.'; - @override - String get welcomePillarsHeader => 'WIE ES ZUSAMMENPASST'; - @override String get welcomePillarHubTitle => 'Hub'; diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index beb4c5d..ff2943a 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -21,9 +21,6 @@ class AppLocalizationsEn extends AppLocalizations { String get welcomeHeroSubtitle => 'Deterministic workflow engine for AI-assisted document processing in regulated environments.'; - @override - String get welcomePillarsHeader => 'HOW IT FITS TOGETHER'; - @override String get welcomePillarHubTitle => 'Hub'; diff --git a/lib/main.dart b/lib/main.dart index e4509c8..93999ab 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -26,7 +26,7 @@ import 'widgets/widgets.dart'; /// Studio's own build version. Bump on every UI commit so the /// running app self-identifies — visible in the sidebar header /// and quick-glance proof that you're seeing the current build. -const String kStudioVersion = '0.39.0'; +const String kStudioVersion = '0.39.1'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -146,6 +146,15 @@ class _StudioShellState extends State { selectedIcon: Icons.waving_hand, page: WelcomePage(), ), + // Store moved to slot 2 in v0.39.1 — it's the + // operator's daily-use surface and belongs above Doctor, + // which is a diagnostics page. + _NavPage( + id: 'store', + icon: Icons.storefront_outlined, + selectedIcon: Icons.storefront, + page: StorePage(), + ), _NavPage( id: 'doctor', icon: Icons.health_and_safety_outlined, @@ -157,12 +166,6 @@ class _StudioShellState extends State { // the Store's detail sheet, and the Store with the // "Installed" filter covers the listing role. Cmd+K still // opens FaiModuleSheet for quick info. - _NavPage( - id: 'store', - icon: Icons.storefront_outlined, - selectedIcon: Icons.storefront, - page: StorePage(), - ), _NavPage( id: 'flows', icon: Icons.account_tree_outlined, diff --git a/lib/pages/welcome.dart b/lib/pages/welcome.dart index 1ffd36b..6bf1449 100644 --- a/lib/pages/welcome.dart +++ b/lib/pages/welcome.dart @@ -52,8 +52,6 @@ class WelcomePage extends StatelessWidget { // path beats educational content. Auto-hides // once the operator dismisses it. _OnboardingChecklist(), - _SectionLabel(textKey: _SectionLabelKey.pillars), - SizedBox(height: FaiSpace.md), _PillarRow(), SizedBox(height: FaiSpace.xxl), _SectionLabel(textKey: _SectionLabelKey.trust), @@ -143,7 +141,7 @@ class _Hero extends StatelessWidget { } } -enum _SectionLabelKey { pillars, trust, docs } +enum _SectionLabelKey { trust, docs } class _SectionLabel extends StatelessWidget { final _SectionLabelKey textKey; @@ -154,7 +152,6 @@ class _SectionLabel extends StatelessWidget { final theme = Theme.of(context); final l = AppLocalizations.of(context)!; final text = switch (textKey) { - _SectionLabelKey.pillars => l.welcomePillarsHeader, _SectionLabelKey.trust => l.welcomeTrustHeader, _SectionLabelKey.docs => l.welcomeDocsHeader, }; @@ -210,20 +207,28 @@ class _PillarRow extends StatelessWidget { ], ); } - return Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - for (var i = 0; i < pillars.length; i++) ...[ - if (i > 0) const SizedBox(width: FaiSpace.md), - Expanded( - child: _Pillar( - icon: pillars[i].$1, - title: pillars[i].$2, - body: pillars[i].$3, + // IntrinsicHeight bounds the Row's height so + // `crossAxisAlignment: stretch` has something to + // stretch against. Without it the Row inherits the + // unbounded height of the surrounding + // `SingleChildScrollView` and Flutter throws + // "BoxConstraints forces an infinite height". + return IntrinsicHeight( + child: Row( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + for (var i = 0; i < pillars.length; i++) ...[ + if (i > 0) const SizedBox(width: FaiSpace.md), + Expanded( + child: _Pillar( + icon: pillars[i].$1, + title: pillars[i].$2, + body: pillars[i].$3, + ), ), - ), + ], ], - ], + ), ); }, ); @@ -683,8 +688,21 @@ class _DocsRow extends StatelessWidget { LayoutBuilder( builder: (context, constraints) { final twoCols = constraints.maxWidth >= 640; - final cardWidth = - twoCols ? (constraints.maxWidth - FaiSpace.md) / 2 : double.infinity; + // Narrow windows stack to a single column. Putting + // `width: double.infinity` SizedBoxes into a Wrap + // breaks Wrap's intrinsic-width math; a Column with + // unconstrained child widths is the correct fit. + if (!twoCols) { + return Column( + children: [ + for (var i = 0; i < _kDocs.length; i++) ...[ + if (i > 0) const SizedBox(height: FaiSpace.md), + _DocCard(entry: _kDocs[i]), + ], + ], + ); + } + final cardWidth = (constraints.maxWidth - FaiSpace.md) / 2; return Wrap( spacing: FaiSpace.md, runSpacing: FaiSpace.md, diff --git a/pubspec.yaml b/pubspec.yaml index 03a6510..115ced2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: fai_studio description: "F∆I Studio — desktop GUI for the F∆I hub" publish_to: 'none' -version: 0.39.0 +version: 0.39.1 environment: sdk: ^3.11.0-200.1.beta