Files
pluriwave/lib/widgets/pluri_layout.dart
T
FreeTLab b8f078bc14 feat(nav): rebuild the bottom bar as the prototype's balloon bar
The functional redesign never touched pluri_bottom_navigation.dart, so the
bar kept the old glass + magenta/coral language while every other surface
moved on. Rebuilds it to prototype t4/4a: a 52px opaque #0A1B24 pill with a
110x74 balloon raised over the active tab, a teal radial glow behind it, the
active item lifted 15px with its label, and inactive items reduced to a 23px
icon at 46% opacity.

The five tabs and their PluriIconGlyph icons are unchanged, per the standing
decision — only the bar's shape, colour and behaviour move.

altura and PluriLayout.bottomChromeInset are both asserted against the real
laid-out height rather than hardcoded guesses.
2026-07-29 20:00:30 +02:00

61 lines
1.9 KiB
Dart

import 'package:flutter/material.dart';
import '../tema/pluriwave_theme.dart';
import 'mini_reproductor.dart';
import 'pluri_bottom_navigation.dart';
abstract final class PluriLayout {
static const double horizontal = 16;
static const double sectionGap = 12;
static const double panelGap = 12;
static const double compactGap = 8;
/// `app.dart`'s `bottomNavigationBar` stacks `MiniReproductor` above
/// `PluriBottomNavigation` with no gap between them, wrapped in a
/// `SafeArea(minimum: EdgeInsets.only(bottom: compactGap))` — this is that
/// same sum, derived from the two chrome widgets' own measured heights
/// instead of a guessed constant. See
/// `pluri_bottom_navigation_test.dart`'s composed-chrome-height assertion.
static const double bottomChromeInset =
MiniReproductor.altura + PluriBottomNavigation.altura + compactGap;
/// ADR-7(b): `bottomChromeInset` assumes `MiniReproductor` is visible.
/// Escuchar hides it (design's one exception — the embedded hero already
/// shows the same station), so its content needs less bottom padding.
static const double escucharBottomChromeInset =
bottomChromeInset - MiniReproductor.altura;
static const EdgeInsets pageListPadding = EdgeInsets.fromLTRB(
0,
0,
0,
bottomChromeInset,
);
static const EdgeInsets pageContentPadding = EdgeInsets.symmetric(
horizontal: horizontal,
);
static const EdgeInsets sheetPadding = EdgeInsets.all(18);
}
class PluriPanelColumn extends StatelessWidget {
const PluriPanelColumn({super.key, required this.children, this.gap});
final List<Widget> children;
final double? gap;
@override
Widget build(BuildContext context) {
final resolvedGap = gap ?? context.pluriTokens.spacingSm + 4;
return Column(
children: [
for (var i = 0; i < children.length; i++) ...[
if (i > 0) SizedBox(height: resolvedGap),
children[i],
],
],
);
}
}