feat(ui): mobile UI v2 — contrast, avatars, room-list density, compose FAB, gradient login (v1.8.0+12)

From a 7-agent design workflow (3 lenses judged + synthesised). Shipped the
high-impact/low-risk tier:
- message bubbles: self #1265ED (WCAG AA pass), incoming #1C2452 + hairline
- deterministic per-user avatar colours (8-hue brand palette)
- room tile: brighter unread preview, compact density, aligned timestamp
- FAB -> New message (thumb zone), explore -> AppBar
- login + welcome brand gradient, card outlines
- input maxLines cap, bubble max-width viewport fraction, AppBar hairline

All verified on production build in headless Chromium at mobile size.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-04 07:49:53 +10:00
parent a36df1c961
commit d2a2a1ab07
11 changed files with 106 additions and 34 deletions

View File

@@ -10,6 +10,9 @@ import 'package:flutter/material.dart';
abstract final class M8Colours {
static const Color brandBlue = Color(0xFF1265ED);
static const Color accentBlue = Color(0xFF3B8BFF);
// Self message bubble — deeper than accentBlue so white text passes WCAG AA
// (white on #1265ED = 5.11:1; on #3B8BFF = 3.32:1, fails).
static const Color selfBubble = Color(0xFF1265ED);
static const Color darkBackground = Color(0xFF0A0F2E);
static const Color darkSurface = Color(0xFF131A42);
static const Color darkSurfaceVariant = Color(0xFF1C2452);
@@ -43,7 +46,11 @@ ThemeData buildDarkTheme() {
backgroundColor: M8Colours.darkSurface,
foregroundColor: M8Colours.onDarkSurface,
elevation: 0,
scrolledUnderElevation: 2,
surfaceTintColor: Colors.transparent,
shape: const Border(
bottom: BorderSide(color: M8Colours.darkSurfaceVariant),
),
),
navigationBarTheme: NavigationBarThemeData(
backgroundColor: M8Colours.darkSurface,