Files
photo-live/apps/mobile/lib/ui/tokens.dart
T
浅念 6074fc8ed3 feat(ui06): App line A0-A7 — nav pill removal, light segments, bare summary, token alignment to app-preview
- tokens:次文字 #69778E、soft/card-border/seg 色组、输入圆角 10(kRadiusField)
- theme:导航 indicatorColor 透明+显式选中蓝;卡片去阴影改 1px #EDF0F5 边框;输入边框同步
- 新组件 SegmentTabs(#EDF1F6 轨道/选中实蓝/light 浅蓝变体/null 无高亮)替换 M3 SegmentedButton
- 上传中心:摘要去白卡直排+主数字 32/40;completed 次级筛选无高亮语义保留
- 相册卡 scrim 30% 起 #0C1728E8;导航角标红底白字白边;登录主标题 27/700
- theme_test 三处旧规格断言随 UI06 值更新;397/397 全绿、analyze 0 issues
- 真机证据:MuMu + 测试服务器 API,登录/相册/详情/上传 4 页截图确认达标
- 登记偏差:语义色保持对比度合规深色版;视口矩阵随 G2;详见验收记录 §6

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 08:09:20 +08:00

107 lines
4.6 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/// UI-01 设计令牌(方案 §3.1/§3.2):色彩、间距、圆角、动效时长。
///
/// - 语义色(成功/等待/错误)不占用 Material ColorScheme 角色(secondary
/// 虽承载等待色,但组件层统一走令牌),浅色值为方案基准;深色场景用
/// `*Dark` 变体——深色表面上直接使用浅色基准会跌破对比度目标,组件按
/// [Brightness] 选择(见 StateBadge)。
/// - 间距 4/8/12/16/24/32;页面左右默认 [kSpace16]。
/// - 圆角:卡片 16 / 输入框与按钮 12 / 小标签 8,避免全部做成胶囊。
/// - 动效:轻量状态 [kMotionFast]、轮播/照片过渡 [kMotionCarousel];
/// 系统「减少动态效果」开启时 [motion] 统一归零(禁用非必要动效)。
library;
import 'package:flutter/material.dart';
// ── 语义色(浅色基准,方案 §3.1)──────────────────────────────────────────
/// 成功:已上传等完成事实(#16794B)。
const Color kColorSuccess = Color(0xFF16794B);
/// 等待:等待网络、等待调度(#996300)。
const Color kColorWaiting = Color(0xFF996300);
/// 错误:需要用户处理的失败(#B42318)。
const Color kColorError = Color(0xFFB42318);
/// 信息:中性提示(与主色一致,#1A73E8)。
const Color kColorInfo = Color(0xFF1A73E8);
/// 分隔线:轻分隔,不用粗边框(#E5EAF1)。
const Color kColorDivider = Color(0xFFE5EAF1);
/// 次文字:时间、地点、说明(app-preview --muted #69778E)。
const Color kColorTextSecondary = Color(0xFF69778E);
/// 浅蓝软底(app-preview --soft #EDF4FF):信息提示、tag 底、选中页签。
const Color kColorSoft = Color(0xFFEDF4FF);
/// 卡片细边框(app-preview .card/.group border #EDF0F5;卡为边框形态非阴影)。
const Color kColorCardBorder = Color(0xFFEDF0F5);
/// 分段轨道底(app-preview .tabs #EDF1F6)。
const Color kColorSegTrack = Color(0xFFEDF1F6);
/// 输入框默认边框(app-preview .field input #DBE3EF)。
const Color kColorFieldBorder = Color(0xFFDBE3EF);
/// 浅蓝选中分段(app-preview .tabs.light active:#DBEAFF 底 + #145BB9 字)。
const Color kColorSegLightActive = Color(0xFFDBEAFF);
const Color kColorSegLightActiveText = Color(0xFF145BB9);
// ── 语义色(深色变体:深色表面对应提亮值)──────────────────────────────
/// 成功(深色表面用)。
const Color kColorSuccessDark = Color(0xFF34D399);
/// 等待(深色表面用)。
const Color kColorWaitingDark = Color(0xFFFCD34D);
/// 错误(深色表面用)。
const Color kColorErrorDark = Color(0xFFF87171);
/// 信息(深色表面用,与深色主色一致)。
const Color kColorInfoDark = Color(0xFF8AB4F8);
/// 次文字(深色表面用)。
const Color kColorTextSecondaryDark = Color(0xFFA6B0C0);
/// 摄影深色背景(§3:相机取景/大图浏览 #10161E)。
///
/// 深色摄影界面**恒深色**——不随系统主题切换(spec §3),文字/图标直接
/// 用固定白/白70,不读主题色。
const Color kColorPhotoBackdrop = Color(0xFF10161E);
// ── 间距(4/8/12/16/24/32)───────────────────────────────────────────────
const double kSpace4 = 4.0;
const double kSpace8 = 8.0;
const double kSpace12 = 12.0;
const double kSpace16 = 16.0;
const double kSpace24 = 24.0;
const double kSpace32 = 32.0;
// ── 圆角(卡片 16 / 按钮 12 / 输入框 10 / 小标签 8)──────────────────────
const double kRadiusCard = 16.0;
const double kRadiusInput = 12.0;
const double kRadiusField = 10.0;
const double kRadiusBadge = 8.0;
// ── 动效时长(轻量 150-220ms / 轮播 250-350ms)────────────────────────
/// 轻量状态过渡(选中态、chip 切换等)。
const Duration kMotionFast = Duration(milliseconds: 180);
/// 轮播/照片过渡。
const Duration kMotionCarousel = Duration(milliseconds: 300);
/// 「减少动态效果」开启时的时长(等价禁用非必要动效)。
const Duration kMotionReduce = Duration.zero;
/// 当前上下文的动效时长:默认 [kMotionFast],`carousel: true` 取
/// [kMotionCarousel];系统「减少动态效果」开启时一律 [kMotionReduce]。
Duration motion(BuildContext context, {bool carousel = false}) {
if (MediaQuery.disableAnimationsOf(context)) return kMotionReduce;
return carousel ? kMotionCarousel : kMotionFast;
}