miler map

This commit is contained in:
2026-09-09 12:55:23 +05:30
parent 074cc0eccf
commit 127fa062ed
143 changed files with 4315 additions and 2291 deletions

View File

@@ -37,6 +37,19 @@ class ColorConstants {
static const Color surfaceTint = Color(0xFF960019);
// Primary Red
/// ── The app bar's own red ──
///
/// The brand bar is painted in a two-stop gradient, and these are its stops.
/// They were literals inside `home_header.dart`, which was fine while the bar
/// was the only thing wearing them — Home's trip panel wears the same red
/// now, and a panel that is *nearly* the app bar's colour reads as a mistake
/// rather than as a family. One definition, so they cannot drift apart.
///
/// Not [primary]: that is the accent the app draws buttons and rules in, and
/// it is a cooler, deeper crimson. The bar has always been this warmer brick.
static const Color brandBarTop = Color(0xFFA51C1C);
static const Color brandBarBottom = Color(0xFF8B1A1A);
static const Color primary = Color(0xFF960019);
static const Color onPrimary = Color(0xFFFFFFFF);
static const Color primaryContainer = Color(0xFFC01227);

View File

@@ -3,41 +3,26 @@ import 'package:flutter/material.dart';
class FontConstants {
/// ── The app's typeface ──
///
/// Poppins: geometric, OFL-licensed, and the one every screen now reads from.
/// It replaced Manrope, which was itself a stand-in for Uber Move.
/// Manrope: a free, OFL-licensed geometric sans, bundled as a single
/// variable font (`assets/fonts/Manrope/Manrope-VF.ttf`) and chosen as the
/// closest legal stand-in for Uber Move, which is proprietary.
///
/// **Read this before changing it.** The family was already declared in
/// `pubspec.yaml` as `poppins`, with a lowercase path on every one of its
/// seven assets, while the files on disk are `assets/fonts/Poppins/Poppins-*`.
/// Asset bundling is case-sensitive on both platforms, so not one of them
/// resolved: anything asking for the family fell back to Roboto and no error
/// was raised anywhere. The declaration is fixed and all seven static weights
/// are registered — Poppins ships as separate files rather than a variable
/// font, and without explicit 800/900 entries Flutter synthesises them by
/// smearing SemiBold, which is what makes a heading look muddy at exactly the
/// size it is meant to be read from.
/// ── The weight scale is calibrated for THIS family ──
/// **Poppins was tried here and reverted.** It is declared in `pubspec.yaml`
/// and its seven static weights do resolve, so it is one string away if it is
/// ever wanted again — but it runs optically far heavier than Manrope at
/// every grade: geometric, wide bowls, thick stems. Swapping the family
/// alone turned the whole app bold, headings especially, and stepping the
/// weight scale down a grade to compensate was not enough to undo it.
///
/// Poppins runs optically heavier than Manrope at every grade: it is
/// geometric, its bowls are wide and its stems thick, so `w800` here is far
/// darker on the page than `w800` was in a variable Manrope. The whole scale
/// was tuned against Manrope and came across a grade too heavy — headings
/// read as shouting and body copy as bold.
///
/// Every weight in `lib/` (outside `lib/xpress`, which is Proxima Nova) was
/// stepped down one grade: 900→800, 800→700, 700→600, 600→500. The *relative*
/// hierarchy is untouched — each level is still one step from its neighbour —
/// so nothing lost its rank; the whole run just sits where it should for this
/// typeface.
///
/// **If the family changes again, re-tune this.** A weight is a number, not a
/// design: what it looks like belongs to the font.
static const String fontFamily = 'Poppins';
/// **The weight scale below is calibrated for THIS family.** If the family
/// changes again, re-tune it — a weight is a number, not a design; what it
/// looks like belongs to the font.
static const String fontFamily = 'Manrope';
/// Only ever reached for a glyph Poppins does not carry. Manrope covers the
/// Only ever reached for a glyph Manrope does not carry. Manrope covers the
/// Latin and currency sets the app uses, so this is a safety net rather than
/// a second typeface in the design.
static String fontFamilyFallback = 'Manrope';
static String fontFamilyFallback = 'PlusJakartaSans';
// Typography scale
static const double displayLg = 32.0;
@@ -50,21 +35,21 @@ class FontConstants {
static TextStyle displayLgStyle = const TextStyle(
fontSize: 32,
fontWeight: FontWeight.w600,
fontWeight: FontWeight.w700,
letterSpacing: -0.64,
fontFamily: fontFamily,
);
static TextStyle headlineMdStyle = const TextStyle(
fontSize: 24,
fontWeight: FontWeight.w600,
fontWeight: FontWeight.w700,
letterSpacing: -0.24,
fontFamily: fontFamily,
);
static TextStyle headlineSmStyle = const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
fontWeight: FontWeight.w600,
letterSpacing: -0.2,
fontFamily: fontFamily,
);
@@ -83,7 +68,7 @@ class FontConstants {
static TextStyle labelBoldStyle = const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,
fontWeight: FontWeight.w700,
fontFamily: fontFamily,
);

View File

@@ -36,13 +36,10 @@ class AppTheme {
},
),
fontFamily: FontConstants.fontFamily,
// Manrope first: it is bundled, so its coverage is guaranteed on every
// device, and it is what backs Poppins up for anything Poppins does not
// carry. The platform families behind it are the last resort. Poppins is
// missing U+2192 among others — a glyph the app no longer renders as a
// character, but the net belongs here rather than in a rule nobody
// remembers.
fontFamilyFallback: const ['Manrope', 'Roboto', 'sans-serif'],
// Manrope is the family above and is bundled, so its coverage is
// guaranteed on every device; these are only reached for a glyph it does
// not carry, and the platform families are the last resort.
fontFamilyFallback: const ['Roboto', 'sans-serif'],
textTheme: ThemeData.light().textTheme.apply(
fontFamily: FontConstants.fontFamily,
),
@@ -116,7 +113,7 @@ class AppTheme {
),
textStyle: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
fontWeight: FontWeight.w700,
fontFamily: FontConstants.fontFamily,
),
),
@@ -153,7 +150,7 @@ class AppTheme {
),
textStyle: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
fontWeight: FontWeight.w700,
fontFamily: FontConstants.fontFamily,
),
),
@@ -162,7 +159,7 @@ class AppTheme {
style: TextButton.styleFrom(
foregroundColor: _primary,
textStyle: const TextStyle(
fontWeight: FontWeight.w500,
fontWeight: FontWeight.w600,
fontFamily: FontConstants.fontFamily,
),
),

View File

@@ -64,7 +64,7 @@ class MilerType {
/// The one thing a screen is about. One per screen, or none.
static TextStyle get hero => TextStyle(
fontSize: 28.sp,
fontWeight: FontWeight.w700,
fontWeight: FontWeight.w800,
letterSpacing: -0.9,
height: 1.08,
color: ColorConstants.slateText,
@@ -74,7 +74,7 @@ class MilerType {
/// App bar titles and sheet headings.
static TextStyle get pageTitle => TextStyle(
fontSize: 22.sp,
fontWeight: FontWeight.w700,
fontWeight: FontWeight.w800,
letterSpacing: -0.6,
height: 1.15,
color: ColorConstants.slateText,
@@ -84,7 +84,7 @@ class MilerType {
/// A stop name in a list, a section heading inside a screen.
static TextStyle get cardTitle => TextStyle(
fontSize: 19.sp,
fontWeight: FontWeight.w700,
fontWeight: FontWeight.w800,
letterSpacing: -0.4,
height: 1.2,
color: ColorConstants.slateText,
@@ -94,7 +94,7 @@ class MilerType {
/// Addresses, running copy, the title line of a compact row.
static TextStyle get body => TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w500,
fontWeight: FontWeight.w600,
letterSpacing: -0.2,
height: 1.35,
color: ColorConstants.slateText,
@@ -105,7 +105,7 @@ class MilerType {
/// explains, and explanation is secondary to the thing being explained.
static TextStyle get caption => TextStyle(
fontSize: 15.sp,
fontWeight: FontWeight.w500,
fontWeight: FontWeight.w600,
height: 1.4,
color: ColorConstants.secondaryText,
fontFamily: _family,
@@ -114,7 +114,7 @@ class MilerType {
/// Metadata, timestamps, chip text, the second line of a row.
static TextStyle get label => TextStyle(
fontSize: 13.sp,
fontWeight: FontWeight.w500,
fontWeight: FontWeight.w600,
height: 1.35,
color: ColorConstants.secondaryText,
fontFamily: _family,
@@ -124,7 +124,7 @@ class MilerType {
/// expected to be read outdoors.
static TextStyle get micro => TextStyle(
fontSize: 12.5.sp,
fontWeight: FontWeight.w500,
fontWeight: FontWeight.w600,
height: 1.3,
color: ColorConstants.secondaryText,
fontFamily: _family,
@@ -134,7 +134,7 @@ class MilerType {
/// the reason most groups in this app need no outline.
static TextStyle get eyebrow => TextStyle(
fontSize: 11.sp,
fontWeight: FontWeight.w700,
fontWeight: FontWeight.w800,
letterSpacing: 1.2,
height: 1.3,
color: ColorConstants.secondaryText,
@@ -150,7 +150,7 @@ class MilerType {
/// number, resolved without `.sp`.
static const TextStyle pageTitleFixed = TextStyle(
fontSize: 22,
fontWeight: FontWeight.w700,
fontWeight: FontWeight.w800,
letterSpacing: -0.6,
height: 1.15,
color: ColorConstants.slateText,
@@ -165,7 +165,7 @@ class MilerType {
/// them lines up.
static TextStyle figure(double size, {Color? color}) => TextStyle(
fontSize: size.sp,
fontWeight: FontWeight.w700,
fontWeight: FontWeight.w800,
letterSpacing: -0.3,
height: 1.1,
fontFeatures: const [FontFeature.tabularFigures()],
@@ -183,7 +183,7 @@ class MilerType {
? 15
: 14)
.sp,
fontWeight: FontWeight.w600,
fontWeight: FontWeight.w700,
letterSpacing: -0.1,
color: ColorConstants.onAccent,
fontFamily: _family,
@@ -198,7 +198,7 @@ class MilerType {
extension MilerTypeTint on TextStyle {
TextStyle on(Color color) => copyWith(color: color);
TextStyle get bold => copyWith(fontWeight: FontWeight.w700);
TextStyle get bold => copyWith(fontWeight: FontWeight.w800);
TextStyle get semibold => copyWith(fontWeight: FontWeight.w600);
TextStyle get semibold => copyWith(fontWeight: FontWeight.w700);
}