feat: enhance UI, branding assets, onboarding flow, and screen layouts
This commit is contained in:
78
lib/widgets/krow_wordmark.dart
Normal file
78
lib/widgets/krow_wordmark.dart
Normal file
@@ -0,0 +1,78 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../core/theme.dart';
|
||||
|
||||
/// The brand wordmark.
|
||||
///
|
||||
/// The asset is an alpha mask — the shape lives in the alpha channel — so one
|
||||
/// file tints to any colour. `Image.asset` blends a `color` with `srcIn` by
|
||||
/// default, which is the same thing the brand sheet did with a CSS mask.
|
||||
///
|
||||
/// Sized by width, because the mark is a fixed 3.06:1 and the width is what
|
||||
/// has to sit within a layout.
|
||||
class KrowWordmark extends StatelessWidget {
|
||||
const KrowWordmark({super.key, this.width = 132, this.color});
|
||||
|
||||
final double width;
|
||||
final Color? color;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Image.asset(
|
||||
'assets/images/krow_logo.png',
|
||||
width: width,
|
||||
color: color ?? KrowPalette.yellow,
|
||||
filterQuality: FilterQuality.medium,
|
||||
semanticLabel: 'KROW',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The line that tops each main tab: the wordmark on the left, and whatever
|
||||
/// that tab already had up there on the right — an action button, or its
|
||||
/// caption. Putting the mark on the existing line rather than a new one keeps
|
||||
/// the brand consistent across tabs without spending header height on it.
|
||||
class HeaderBrandLine extends StatelessWidget {
|
||||
const HeaderBrandLine({super.key, this.trailing});
|
||||
|
||||
final Widget? trailing;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
// White rather than yellow: the accent is already carrying the avatar
|
||||
// and the money figures, and a third yellow element leads nowhere.
|
||||
const KrowWordmark(width: 62, color: Colors.white),
|
||||
const SizedBox(width: 12),
|
||||
if (trailing != null)
|
||||
Expanded(
|
||||
child: Align(alignment: Alignment.centerRight, child: trailing),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The small uppercase caption that sits beside the wordmark on a tab header.
|
||||
class HeaderEyebrow extends StatelessWidget {
|
||||
const HeaderEyebrow(this.text, {super.key});
|
||||
|
||||
final String text;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(
|
||||
text.toUpperCase(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.right,
|
||||
style: TextStyle(
|
||||
fontSize: 9.5,
|
||||
letterSpacing: 1.5,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.white.withValues(alpha: 0.5),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user