feat(learn,todo,train,meditate,ui): the navigation bar flush with the foot, a fade above it

Below medium windows the frame's bar is Material 3 Expressive's again,
flush with the window's foot (decided 7 Nov 2026 by the developer): the
theme's NavigationBar across the whole width, 64 dp in its own colour,
running on beneath the system's bar as Material's does. Right above it a
fade 32 dp high, from the background of the screen in view (the
ScreenTint's, the theme's surface before a screen claims one) made
see-through to that background, so what scrolls on beneath the bar fades
out rather than being cut off; taps pass through it. The rail of wider
windows stays as it was.

halkyon_ui's FloatingNavigationBar becomes FlushNavigationBar, its side
margin, lift and rounded card gone. Its coverOf is now the whole room
content leaves at its end, the system's bar included (the body's bottom
padding: bar, fade and system's bar inside the frame, the system's bar
alone outside it), and floating buttons rise by buttonLiftOf, the same
without the system's bar, which a Scaffold keeps them clear of itself.
Lists, Todo's hour grid and the Plan's sheet keep using coverOf; the
Profile's list no longer adds the system's bar a second time.

Whats-New: The navigation bar sits at the bottom edge again, with a soft fade above it.
Whats-New-De: Die Navigationsleiste sitzt wieder am unteren Rand, mit einem sanften Übergang darüber.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-08 00:04:18 +01:00
commit 05db5e2f45
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64
5 changed files with 425 additions and 217 deletions

View file

@ -39,7 +39,7 @@ class const CourseScreen({required final String courseId, super.key})
16,
16,
16,
16 + FloatingNavigationBar.coverOf(context),
16 + FlushNavigationBar.coverOf(context),
),
children: [
Text(

View file

@ -84,7 +84,7 @@ class _LibraryItemScreenState() extends State<LibraryItemScreen> {
16,
16,
16,
16 + FloatingNavigationBar.coverOf(context),
16 + FlushNavigationBar.coverOf(context),
),
children: [
Row(

View file

@ -69,13 +69,13 @@ class _PracticeScreenState() extends State<PracticeScreen> {
maxWidth: readableContentMaxWidth,
),
child: ListView(
// Room at the end for the navigation bar floating over
// Room at the end for the navigation bar and its fade at
// the foot: the page is in Explore's tab.
padding: EdgeInsets.fromLTRB(
16,
16,
16,
16 + FloatingNavigationBar.coverOf(context),
16 + FlushNavigationBar.coverOf(context),
),
children: [
Row(

View file

@ -8,7 +8,7 @@ import 'package:material_ui/material_ui.dart';
/// The frame around Meditate's tabs (ADR 0038, D1, D2, D14): halkyon_ui's
/// [NavigationFrame], as every Halkyon app's, with Today (where it opens),
/// Explore, the Journal and Profile, a bar floating above the foot below medium windows
/// Explore, the Journal and Profile, a bar flush with the foot below medium windows
/// and a rail with Meditate's icon on top from medium on. Every tab keeps
/// its own stack of screens. After an update, what's new shows once
/// (halkyon_app's [WhatsNewOnUpdate]), where the app is given it.

View file

@ -31,11 +31,11 @@ class const TabScreen({
actions: [...actions, const SizedBox(width: 4)],
),
body: body,
// Clear of the navigation bar floating over the foot on a phone.
// Clear of the navigation bar and its fade at the foot on a phone.
floatingActionButton: switch (floatingActionButton) {
final button? => Padding(
padding: EdgeInsets.only(
bottom: FloatingNavigationBar.coverOf(context),
bottom: FlushNavigationBar.buttonLiftOf(context),
),
child: button,
),
@ -46,7 +46,7 @@ class const TabScreen({
}
/// A tab's cards, one under the other, as wide as readable text, with
/// room at the end for the navigation bar floating over the foot.
/// room at the end for the navigation bar and its fade at the foot.
class const CardColumn({
required final List<Widget> children,
super.key,
@ -61,7 +61,7 @@ class const CardColumn({
12,
8,
12,
12 + FloatingNavigationBar.coverOf(context),
12 + FlushNavigationBar.coverOf(context),
),
children: [
for (final (index, child) in children.indexed) ...[