style: 统一全站深色视觉

This commit is contained in:
Zhou Weidong committed 2026-10-22 22:01:36 +08:00
1 parent 86aa7e0f4f
commit 37e35f4b47
24 files changed
+134 -130

No files matched your search

+16 -16
View File
@@ -35,8 +35,8 @@ abstract final class AppColors {
/// 主操作按下态。
static const bluePressed = Color(0xFFE55A1F);
/// 链接与次要高亮(禁止大面积铺色)。
static const blueSoft = Color(0xFF22D3EE);
/// 链接与次要高亮:统一改用中性浅灰,避免旧青色残留。
static const blueSoft = Color(0xFFB0B0B0);
static const secondary = blueSoft;
static const lavender = blueSoft;
@@ -67,13 +67,13 @@ abstract final class AppColors {
static const onPrimary = Color(0xFFFFFFFF);
/// 页面背景。
static const ink = Color(0xFF0B1020);
static const ink = Color(0xFF000000);
/// 首页/追剧/我的统一的纯黑内容背景。
static const appBackground = Color(0xFF000000);
/// 中性深灰卡片与控件表面。
static const contentCard = Color(0xFF171717);
static const contentCard = Color(0xFF16161A);
static const contentSurface = Color(0xFF1C1C1E);
static const contentChip = Color(0xFF2C2C2E);
static const contentBorder = Color(0x1AFFFFFF);
@@ -105,16 +105,16 @@ abstract final class AppColors {
/// 次级文字与列表 chevron。
static const textPrimary = Color(0xFFFFFFFF);
static const textSecondary = Color(0xFF8E8E93);
static const textTertiary = Color(0xFF9E9E9E);
static const textSecondary = Color(0xFFB0B0B0);
static const textTertiary = Color(0xFF8E8E93);
static const textTabInactive = Color(0xFFB0B0B0);
static const textFilterIcon = Color(0xFF7A7A7E);
/// 原生开屏与冷启动过渡底色。
static const splashInk = ink;
/// 顶部与页面底同色,靠容器层次区分。
static const surfaceTop = ink;
/// 页面顶部暖黑色,渐变底部仍收口到纯黑。
static const surfaceTop = mineGradientTop;
/// 底部导航底色。
static const bar = ink;
@@ -127,13 +127,13 @@ abstract final class AppColors {
static const cardShadow = Color(0x00000000);
/// 卡片与列表容器。
static const card = Color(0xFF151B2E);
static const card = Color(0xFF16161A);
/// 次要卡片表面。
static const cardAlt = card;
static const cardAlt = Color(0xFF101010);
/// 浮层、弹窗、输入与嵌套区域。
static const raised = Color(0xFF1C2436);
static const raised = Color(0xFF1C1C1E);
static const quick = raised;
static const input = raised;
@@ -156,13 +156,13 @@ abstract final class AppColors {
/// 橙色强调文案。
static const accent = blue;
/// 分割线 rgba(255,255,255,0.06)。
static const border = Color(0x0FFFFFFF);
/// 统一卡片描边、分割线与输入框边框。
static const border = Color(0xFF1C1C1E);
/// 玻璃面板描边。
static const glassBorder = Color(0x33FFFFFF);
static const glassSurfaceStart = Color(0xEB1C2436);
static const glassSurfaceEnd = Color(0xD1151B2E);
static const glassSurfaceStart = Color(0xEB16161A);
static const glassSurfaceEnd = Color(0xD1101010);
/// 角标底与文字。
static const badgePink = Color(0x33FF6A8A);
@@ -194,7 +194,7 @@ abstract final class AppColors {
static const inactiveTrack = Color(0x24FFFFFF);
/// 横幅/封面底部渐变。
static const bannerScrimMid = Color(0x8A0B1020);
static const bannerScrimMid = Color(0x8A1A0C07);
static const bannerScrimEnd = Color(0xE6000000);
/// 票券虚线等主色描边。
+14 -10
View File
@@ -8,12 +8,16 @@ import 'app_dimens.dart';
/// 深色视觉主题(默认且唯一)。
abstract final class AppTheme {
/// 页面背景:深色扁平,靠容器层次区分。
/// 页面背景:顶部暖黑、底部纯黑,避免旧深蓝渐变。
static const LinearGradient pageGradient = LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [AppColors.surfaceTop, AppColors.ink],
stops: [0, 0.24],
colors: [
AppColors.mineGradientTop,
AppColors.mineGradientMiddle,
AppColors.mineGradientBottom,
],
stops: [0, 0.4, 0.75],
);
/// 卡片阴影关闭,改用底色与分割线。
@@ -76,7 +80,7 @@ abstract final class AppTheme {
),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: AppColors.secondary,
foregroundColor: AppColors.primary,
shape: RoundedRectangleBorder(borderRadius: _buttonRadius),
),
),
@@ -107,12 +111,12 @@ abstract final class AppTheme {
),
outlinedButtonTheme: OutlinedButtonThemeData(
style: ButtonStyle(
foregroundColor: const WidgetStatePropertyAll(AppColors.blue),
foregroundColor: const WidgetStatePropertyAll(AppColors.textPrimary),
minimumSize: const WidgetStatePropertyAll(
Size(0, AppDimens.buttonHeight),
),
side: const WidgetStatePropertyAll(
BorderSide(color: AppColors.border),
BorderSide(color: AppColors.mineOutline),
),
shape: WidgetStatePropertyAll(
RoundedRectangleBorder(borderRadius: _buttonRadius),
@@ -148,20 +152,20 @@ abstract final class AppTheme {
),
),
appBarTheme: const AppBarTheme(
backgroundColor: AppColors.card,
foregroundColor: AppColors.onSurface,
backgroundColor: AppColors.transparent,
foregroundColor: AppColors.textPrimary,
elevation: 0,
scrolledUnderElevation: 0,
surfaceTintColor: AppColors.transparent,
systemOverlayStyle: SystemUiOverlayStyle.light,
titleTextStyle: TextStyle(
color: AppColors.onSurface,
color: AppColors.textPrimary,
fontFamily: 'Outfit',
fontSize: AppDimens.pageTitle,
fontWeight: FontWeight.w800,
),
),
iconTheme: const IconThemeData(color: AppColors.onSurface),
iconTheme: const IconThemeData(color: AppColors.textPrimary),
dividerTheme: const DividerThemeData(
color: AppColors.border,
thickness: 1,
+15 -11
View File
@@ -3,6 +3,7 @@
import 'package:flutter/material.dart';
import '../theme/app_colors.dart';
import '../theme/app_theme.dart';
import 'subpage_header.dart';
/// 二级页面通用骨架:返回栏 + 标题/副标题 + 可滚动内容,无底部导航。
@@ -27,17 +28,20 @@ class PlainPageScaffold extends StatelessWidget {
return Scaffold(
key: pageKey,
backgroundColor: AppColors.ink,
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppSubpageHeader(
title: title,
subtitle: subtitle,
backKey: backKey,
),
Expanded(child: child),
],
body: DecoratedBox(
decoration: const BoxDecoration(gradient: AppTheme.pageGradient),
child: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppSubpageHeader(
title: title,
subtitle: subtitle,
backKey: backKey,
),
Expanded(child: child),
],
),
),
),
);
+14 -22
View File
@@ -14,9 +14,7 @@ const double _subtitleFontSize = 12;
const double _actionGap = 8;
const double _iconSize = 22;
const double _iconWeight = 600;
const double _borderWidth = 1;
const double _shadowBlur = 8;
const Offset _lightShadowOffset = Offset(0, 2);
/// 二级页面统一圆形操作按钮,返回、分享和更多共用同一尺寸与表面样式。
class AppSubpageCircleButton extends StatelessWidget {
@@ -47,24 +45,18 @@ class AppSubpageCircleButton extends StatelessWidget {
key: const Key('subpage-back-shadow'),
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: dark ? AppColors.shadowSoft : AppColors.shadowSubtle,
blurRadius: _shadowBlur,
offset: dark ? Offset.zero : _lightShadowOffset,
),
],
boxShadow: dark
? const [
BoxShadow(
color: AppColors.shadowSoft,
blurRadius: _shadowBlur,
),
]
: const [],
),
child: Material(
color: dark ? AppColors.headerScrim : AppColors.card,
shape: CircleBorder(
side: dark
? BorderSide.none
: const BorderSide(
color: AppColors.border,
width: _borderWidth,
),
),
color: dark ? AppColors.headerScrim : AppColors.transparent,
shape: const CircleBorder(),
clipBehavior: Clip.antiAlias,
child: InkWell(
customBorder: const CircleBorder(),
@@ -72,7 +64,7 @@ class AppSubpageCircleButton extends StatelessWidget {
child: Center(
child: Icon(
icon,
color: AppColors.onSurface,
color: dark ? AppColors.onSurface : AppColors.textPrimary,
size: _iconSize,
weight: _iconWeight,
),
@@ -85,7 +77,7 @@ class AppSubpageCircleButton extends StatelessWidget {
}
}
/// 二级页面统一返回按钮,浅色页使用白底描边,深色页使用半透明黑底。
/// 二级页面统一返回按钮,普通页透明,沉浸页使用半透明黑底。
class AppSubpageBackButton extends StatelessWidget {
const AppSubpageBackButton({
super.key,
@@ -133,8 +125,8 @@ class AppSubpageHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
final foreground = AppColors.onSurface;
final secondary = AppColors.muted;
final foreground = AppColors.textPrimary;
final secondary = AppColors.textSecondary;
return SizedBox(
key: const Key('subpage-header'),
height: subtitle == null ? _height : _heightWithSubtitle,