fix(ui): make screen backgrounds full-bleed instead of content-sized

The gradient Container in the playlist selection and admin screens sized
itself to its content rather than the viewport: under the loose body
constraints, SingleChildScrollView and Wrap both shrink-wrap, so the
gradient was painted only across a 436 px band (48 padding + 340 card +
48 padding) with the rest of the screen falling through to bare black.
BoxConstraints.expand() forces full coverage.

Also:
- both screens now use AppColors.backgroundGradient. The previous ramp
  ran surfaceContainerLowest -> background -> baseLevel0, i.e. dark to
  lighter to dark, which put a pale band across the middle
- the playlist card was a 3% cream translucent plate, so it took on
  whatever sat behind it instead of resting on it; it is now an opaque
  surface (surfaceContainerLow, surfaceContainerHigh on hover) with the
  lift() shadow at rest and the ember focus halo on hover
- Scaffold backgroundColor pinned to baseLevel0 so route transitions
  never flash pure black

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 5 committed 2026-08-10 21:57:35 +02:00
1 parent ad3e970c8d
commit ef744c215e
2 files changed
+27 -33

No files matched your search

+5 -8
View File
@@ -24,16 +24,13 @@ class AdminPanel extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
backgroundColor: AppColors.baseLevel0,
body: Container(
// Meme precaution que sur l'ecran de selection de playlist : sans
// contrainte d'expansion, le degrade ne couvre que le contenu.
constraints: const BoxConstraints.expand(),
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
AppColors.surfaceVariant,
AppColors.background,
],
),
gradient: AppColors.backgroundGradient,
),
child: const AdminContent(),
),
@@ -5,6 +5,7 @@ import 'package:google_fonts/google_fonts.dart';
import '../../../core/services/playlist_api_service.dart';
import '../../../core/models/playlist_config.dart';
import '../../../core/theme/app_colors.dart';
import '../../../core/theme/app_theme.dart';
import '../../auth/providers/auth_provider.dart';
import '../providers/xtream_provider.dart';
@@ -24,6 +25,9 @@ class PlaylistSelectionScreen extends ConsumerWidget {
return Scaffold(
extendBodyBehindAppBar: true,
// Filet de securite : meme pendant une transition de route, le fond
// reste dans la palette au lieu de virer au noir pur.
backgroundColor: AppColors.baseLevel0,
appBar: AppBar(
title: Text(
'Select Playlist',
@@ -57,16 +61,14 @@ class PlaylistSelectionScreen extends ConsumerWidget {
],
),
body: Container(
// `BoxConstraints.expand()` est indispensable ici : sous les
// contraintes laches du body, ce Container se dimensionnait sur son
// contenu (SingleChildScrollView -> Wrap shrink-wrappent tous les
// deux), si bien que le degrade n'etait peint que sur un rectangle
// de la taille des cartes, le reste de l'ecran restant noir.
constraints: const BoxConstraints.expand(),
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
AppColors.surfaceContainerLowest,
AppColors.background,
AppColors.baseLevel0,
],
),
gradient: AppColors.backgroundGradient,
),
child: SafeArea(
child: LayoutBuilder(
@@ -208,26 +210,21 @@ class _PlaylistCardState extends State<_PlaylistCard> {
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
decoration: BoxDecoration(
// Surface OPAQUE : une plaque a 3 % de creme prenait la couleur du
// fond et flottait sans jamais se poser dessus. Un cran de la
// hierarchie de surfaces ancre la carte, l'ombre fait le relief.
color: _isHovered
? AppColors.onSurface.withOpacity(0.1)
: AppColors.onSurface.withOpacity(0.03),
borderRadius: BorderRadius.circular(24),
? AppColors.surfaceContainerHigh
: AppColors.surfaceContainerLow,
borderRadius: BorderRadius.circular(AppTheme.radiusXl),
border: Border.all(
color: _isHovered
? AppColors.primary.withOpacity(0.5)
: AppColors.onSurface.withOpacity(0.08),
width: 1.5,
? AppColors.primaryContainer
: AppColors.glassLevel1Border,
width: _isHovered ? 2 : 1,
),
boxShadow: _isHovered
? [
BoxShadow(
color: AppColors.primary.withOpacity(0.2),
blurRadius: 30,
spreadRadius: -5,
offset: const Offset(0, 10),
),
]
: [],
boxShadow:
_isHovered ? AppColors.emberFocus() : AppColors.lift(),
),
padding: const EdgeInsets.all(24),
child: Column(