140 lines
6.0 KiB
Dart
140 lines
6.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
|
|
import '../../../constant/colors.dart';
|
|
|
|
/// ─────────────────────────────────────────────────────────────────────────
|
|
/// Route Planner — Design System
|
|
///
|
|
/// A single source of truth for the visual language of the ride-planning
|
|
/// surface. Inspired by best-in-class ride-hailing apps: calm neutrals,
|
|
/// a strong navy primary, and semantic colors for the route timeline
|
|
/// (origin = green, stops = amber/violet, destination = red).
|
|
///
|
|
/// This file is pure presentation. It never touches controllers.
|
|
/// ─────────────────────────────────────────────────────────────────────────
|
|
class RP {
|
|
RP._();
|
|
|
|
// ── Radii ──────────────────────────────────────────────────────────────
|
|
static const double rSheet = 28;
|
|
static const double rCard = 20;
|
|
static const double rField = 16;
|
|
static const double rChip = 14;
|
|
static const double rPill = 999;
|
|
|
|
// ── Motion ─────────────────────────────────────────────────────────────
|
|
static const Duration fast = Duration(milliseconds: 180);
|
|
static const Duration medium = Duration(milliseconds: 360);
|
|
static const Curve ease = Curves.easeOutCubic;
|
|
|
|
// ── Semantic route colors ──────────────────────────────────────────────
|
|
static const Color origin = Color(0xFF16A34A); // green — pickup / start
|
|
static const Color destination = Color(0xFFEF4444); // red — drop-off
|
|
static const Color stop1 = Color(0xFFF59E0B); // amber — first stop
|
|
static const Color stop2 = Color(0xFF7C3AED); // violet — second stop
|
|
static Color get brand => AppColor.primaryColor;
|
|
|
|
static Color stopColor(int index) => index == 0 ? stop1 : stop2;
|
|
|
|
// ── Surfaces (theme-aware) ─────────────────────────────────────────────
|
|
static bool get isDark => Get.isDarkMode;
|
|
|
|
static Color get sheet =>
|
|
isDark ? const Color(0xFF1C1D21) : const Color(0xFFFFFFFF);
|
|
static Color get sheetElevated =>
|
|
isDark ? const Color(0xFF26272C) : const Color(0xFFFFFFFF);
|
|
static Color get fieldFill =>
|
|
isDark ? const Color(0xFF2A2B31) : const Color(0xFFF4F5F7);
|
|
static Color get chipFill =>
|
|
isDark ? const Color(0xFF2A2B31) : const Color(0xFFF1F3F6);
|
|
static Color get divider =>
|
|
isDark ? const Color(0xFF33343A) : const Color(0xFFECEEF1);
|
|
|
|
// ── Text ───────────────────────────────────────────────────────────────
|
|
static Color get textStrong =>
|
|
isDark ? const Color(0xFFF5F6F8) : const Color(0xFF10131A);
|
|
static Color get textBody =>
|
|
isDark ? const Color(0xFFC7CAD1) : const Color(0xFF3A3F4A);
|
|
static Color get textMuted =>
|
|
isDark ? const Color(0xFF8A8E98) : const Color(0xFF8B9099);
|
|
|
|
// ── Elevation ──────────────────────────────────────────────────────────
|
|
static List<BoxShadow> get sheetShadow => [
|
|
BoxShadow(
|
|
color: Colors.black.withValues(alpha: isDark ? 0.45 : 0.12),
|
|
blurRadius: 40,
|
|
spreadRadius: -6,
|
|
offset: const Offset(0, -8),
|
|
),
|
|
BoxShadow(
|
|
color: Colors.black.withValues(alpha: isDark ? 0.30 : 0.06),
|
|
blurRadius: 14,
|
|
spreadRadius: -4,
|
|
offset: const Offset(0, -2),
|
|
),
|
|
];
|
|
|
|
static List<BoxShadow> get cardShadow => [
|
|
BoxShadow(
|
|
color: Colors.black.withValues(alpha: isDark ? 0.35 : 0.08),
|
|
blurRadius: 24,
|
|
spreadRadius: -8,
|
|
offset: const Offset(0, 8),
|
|
),
|
|
];
|
|
|
|
static List<BoxShadow> glow(Color c, {double intensity = 0.35}) => [
|
|
BoxShadow(
|
|
color: c.withValues(alpha: intensity),
|
|
blurRadius: 16,
|
|
spreadRadius: -2,
|
|
offset: const Offset(0, 4),
|
|
),
|
|
];
|
|
|
|
// ── Text styles ────────────────────────────────────────────────────────
|
|
static TextStyle get title => TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.w800,
|
|
letterSpacing: -0.4,
|
|
color: textStrong,
|
|
);
|
|
|
|
static TextStyle get sectionLabel => TextStyle(
|
|
fontSize: 12.5,
|
|
fontWeight: FontWeight.w700,
|
|
letterSpacing: 0.4,
|
|
color: textMuted,
|
|
);
|
|
|
|
static TextStyle get fieldValue => TextStyle(
|
|
fontSize: 15,
|
|
fontWeight: FontWeight.w700,
|
|
color: textStrong,
|
|
);
|
|
|
|
static TextStyle get fieldHint => TextStyle(
|
|
fontSize: 15,
|
|
fontWeight: FontWeight.w600,
|
|
color: textMuted,
|
|
);
|
|
|
|
static TextStyle get body => TextStyle(
|
|
fontSize: 13.5,
|
|
fontWeight: FontWeight.w500,
|
|
color: textBody,
|
|
);
|
|
|
|
// ── Reusable pieces ────────────────────────────────────────────────────
|
|
/// A short grabber handle used at the top of sheets.
|
|
static Widget grabber() => Container(
|
|
width: 42,
|
|
height: 5,
|
|
decoration: BoxDecoration(
|
|
color: isDark ? Colors.white24 : Colors.black12,
|
|
borderRadius: BorderRadius.circular(RP.rPill),
|
|
),
|
|
);
|
|
}
|