import 'package:flutter/material.dart'; /// 双端唯一视觉 Token。取值只来自 B-91 v2 规范第 2 节,禁止在页面内硬编码色值/字号/间距/圆角。 /// /// 官方 widget 通过 [openim_common] `Styles` 映射到本表(见 apply_official_styles.dart), /// 公司自建页面直接引用本文件。本阶段保留 OpenIM 标识,不做「畅联」换标。 class AppColors { AppColors._(); static const Color primary = Color(0xFF3B87F5); static const Color primaryActive = Color(0xFFEBF3FE); static const Color primaryPressed = Color(0xFF2E75E0); static const Color avatarGray = Color(0xFF8593A8); static const Color pageBg = Color(0xFFFFFFFF); static const Color chatBg = Color(0xFFF5F6F8); static const Color searchBg = Color(0xFFF2F3F5); static const Color bubbleMine = Color(0xFFD6E7FC); static const Color bubbleOther = Color(0xFFFFFFFF); static const Color textPrimary = Color(0xFF1D2129); static const Color textSecondary = Color(0xFF86909C); static const Color danger = Color(0xFFF53F3F); static const Color divider = Color(0xFFEEEEEE); static const Color bannerBg = Color(0xFF3A3F47); static const Color maskBg = Color(0xFF000000); static const Color success = Color(0xFF00B42A); static const Color warning = Color(0xFFFF7D00); /// 通话页纯色深底。与 [textPrimary] 同值(`#1D2129`),不得改用 [maskBg]。 static const Color callBg = textPrimary; } class AppFont { AppFont._(); static const double small = 12; static const double sub = 14; static const double body = 16; static const double title = 18; /// 语音通话计时器,B-91 §2 唯一字号例外。 static const double callTimer = 32; } class AppGap { AppGap._(); static const double x1 = 4; static const double x2 = 8; static const double x3 = 12; static const double x4 = 16; static const double x6 = 24; static const double x8 = 32; static const double x12 = 48; /// 来电拒绝/接听间距,B-91 §4.10。 static const double x24 = 96; } class AppRadius { AppRadius._(); static const double control = 8; static const double modal = 12; static const double bubble = 8; static const double logo = 16; static double avatar(double size) => size * 0.18; } class AppIconSize { AppIconSize._(); static const double sm = 20; static const double md = 22; static const double lg = 24; } /// 安卓语音通话页尺寸,取值只来自 B-91 §4.10。 class AppCallSize { AppCallSize._(); static const double nameTop = 96; static const double avatar = 96; static const double primaryBtn = 64; static const double secondaryBtn = 48; static const double incomingGap = AppGap.x24; static const double minimizeHit = 48; } class AppDuration { AppDuration._(); static const hover = Duration(milliseconds: 100); static const overlay = Duration(milliseconds: 150); static const overlaySwitch = Duration(milliseconds: 100); static const route = Duration(milliseconds: 200); static const toastOut = Duration(milliseconds: 200); static const toastStay = Duration(seconds: 2); static const bannerCollapse = Duration(milliseconds: 300); static const picture = Duration(milliseconds: 200); static const callPage = Duration(milliseconds: 250); static const callEndHold = Duration(milliseconds: 1500); static const callInviteTimeout = Duration(seconds: 60); static const callVibrate = Duration(seconds: 1); } class AppMotion { AppMotion._(); static bool reduce(BuildContext context) => MediaQuery.maybeOf(context)?.disableAnimations ?? false; static Duration of(BuildContext context, Duration normal) => reduce(context) ? Duration.zero : normal; } class AppShadows { AppShadows._(); static const List modal = [ BoxShadow(color: Color(0x14000000), offset: Offset(0, 4), blurRadius: 16), ]; }