Dynamic color: keep card surfaces lighter than the page
In light mode surfaceContainerLow is slightly darker than the OS surface bg maps to, so the selection bar and other cards blended into the page. Use surfaceContainerLowest (light) / surfaceContainer (dark) for NooColors.surface. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
c0a67f3efe
commit
02278a048d
@@ -29,6 +29,13 @@ widgets. Key points:
|
||||
whole app in `main.dart`. When available and `useDynamicColor` is on, the
|
||||
OS-provided `ColorScheme` wins over the seed color — always thread both
|
||||
`dynamicScheme` and `useDynamicColor` through when adding a theme knob.
|
||||
`NooColors.fromDynamicScheme` keeps `bg` on the OS `surface` but picks
|
||||
`surface` (cards, selection bar, rows) from the container roles so it
|
||||
stays lighter than `bg`: `surfaceContainerLowest` (white) in light,
|
||||
`surfaceContainer` in dark. The dynamic_color package seeds the container
|
||||
roles from the primary color rather than the OS palette, and in light mode
|
||||
`surfaceContainerLow` is slightly *darker* than the OS `surface`, which
|
||||
made cards blend into the page ("the selection bar has no background").
|
||||
- **Font**: Inter via `google_fonts`, applied through
|
||||
`GoogleFonts.interTextTheme(...)`. Font files ship in
|
||||
`assets/google_fonts/` (Instrument Sans, Schibsted Grotesk) and
|
||||
|
||||
@@ -139,11 +139,20 @@ class NooColors extends ThemeExtension<NooColors> {
|
||||
/// paints it, not painted directly - using it as-is for a sheet/dialog's
|
||||
/// `barrierColor` hid the screen behind completely instead of dimming it,
|
||||
/// so this uses the fixed palette's already-translucent scrim instead.
|
||||
///
|
||||
/// `surface` (cards, bars, rows) has to read as lighter than `bg`, like
|
||||
/// the fixed palettes' white-on-beige / lifted-on-near-black. In light
|
||||
/// mode `surfaceContainerLow` is a hair *darker* than the OS-provided
|
||||
/// `surface` that [bg] uses, so cards (the selection bar, list rows)
|
||||
/// vanished into the page; `surfaceContainerLowest` (white) doesn't. Dark
|
||||
/// mode uses `surfaceContainer` rather than `...Low` for a bigger step
|
||||
/// off the page.
|
||||
factory NooColors.fromDynamicScheme(ColorScheme cs) {
|
||||
final fixed = cs.brightness == Brightness.dark ? dark : light;
|
||||
final dark = cs.brightness == Brightness.dark;
|
||||
final fixed = dark ? NooColors.dark : NooColors.light;
|
||||
return NooColors(
|
||||
bg: cs.surface,
|
||||
surface: cs.surfaceContainerLow,
|
||||
surface: dark ? cs.surfaceContainer : cs.surfaceContainerLowest,
|
||||
surface2: cs.surfaceContainerHigh,
|
||||
surface3: cs.surfaceContainerHighest,
|
||||
line: cs.outlineVariant,
|
||||
|
||||
@@ -74,6 +74,30 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('NooColors.fromDynamicScheme surfaces', () {
|
||||
for (final brightness in Brightness.values) {
|
||||
test('cards are clearly lighter than the page (${brightness.name})', () {
|
||||
// The OS palette overrides `surface` (what `bg` maps to) but not the
|
||||
// seeded container roles - mimic that mismatch.
|
||||
final seeded = ColorScheme.fromSeed(
|
||||
seedColor: const Color(0xFF3F6B8F),
|
||||
brightness: brightness,
|
||||
);
|
||||
final os = seeded.copyWith(
|
||||
surface: brightness == Brightness.light
|
||||
? const Color(0xFFF7F9FC)
|
||||
: const Color(0xFF101417),
|
||||
);
|
||||
final c = NooColors.fromDynamicScheme(os);
|
||||
// WCAG-style contrast ratio between the card and the page.
|
||||
final hi = c.surface.computeLuminance();
|
||||
final lo = c.bg.computeLuminance();
|
||||
expect(hi, greaterThan(lo));
|
||||
expect((hi + 0.05) / (lo + 0.05), greaterThan(1.04));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
group('NooAvatar', () {
|
||||
testNooWidgets('current user uses accent-soft/accent-text', (
|
||||
tester,
|
||||
|
||||
Reference in New Issue
Block a user