chore: استيراد أولي من سيرو (ecfe7568) — بلا أي تعديل
نسخة كاملة من مستودع سيرو عند ecfe7568 لتكون أساس تطبيق «انطلق». نُسخ المتعقَّب في git فقط (12,509 ملفاً / 302 م.ب) بـ git archive، لا `cp -r` — فاستُثنيت تلقائياً مخلفات البناء (build · node_modules · .dart_tool · .gradle · Pods ≈ 10.7 غ.ب) وكل ما يستثنيه .gitignore. هذا الكوميت **بلا أي تعديل عمداً** حتى يكون كل ما يليه فرقاً مقروءاً مقابل سيرو الأصلي. سيرو نفسه لم يُمسّ. ⚠️ لا يبني بعد: `.env` و`lib/env/env.g.dart` غير متعقَّبين في سيرو (وهذا صحيح — أسرار لكل مستأجر). كل تطبيق فلاتر هنا يحتاج .env خاصاً بانطلق ثم توليد env.g.dart عبر build_runner. لا تُنسخ أسرار سيرو. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
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),
|
||||
),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user