A white page, and cards that still read on it
The canvas was #F1F0EC — a warm grey that made every screen look slightly dull. It is white. ── You cannot have both ── That canvas was not an accident: it was deepened from #F7F6F4 on 2026-09-23 precisely so a white card would sit *on* something and its 1px edge could go quiet. A white card on a white page has nothing to sit on. Measured rather than judged by eye: after the canvas change, a pixel scan across a card boundary on the Orders golden read #FFFFFF from end to end. The shadow contributed nothing findable. The cards had not become subtle, they had disappeared. So the edge comes back. `DmCard` drew its border only for tones that are not white — the warm canvas was doing that job for the white ones — and now draws it for every tone, with the lift still underneath. Border plus a soft shadow is the iOS and Revolut shape rather than the borderless Airbnb one, and that is the price of a white page. Paid deliberately. ── What moved with it ── `surfaceAlt` lifts to #F4F2EF. With a white page it is the only token that makes a surface read as recessed — filled inputs, tiles, skeletons, the sunken card — so it can no longer sit within a point of the canvas. `DmCardTone.sunken` filled itself with the canvas colour, which on a white page is not sunken but invisible. It takes `surfaceAlt`.
This commit is contained in:
@@ -65,7 +65,9 @@ class DmCard extends StatelessWidget {
|
||||
DmCardTone.plain => DmColors.surface,
|
||||
DmCardTone.fill => DmColors.brand,
|
||||
DmCardTone.wash => DmColors.brandSoft,
|
||||
DmCardTone.sunken => DmColors.canvas,
|
||||
// Not the canvas any more: the page is white, and a card filled with
|
||||
// the page colour is not sunken, it is invisible.
|
||||
DmCardTone.sunken => DmColors.surfaceAlt,
|
||||
};
|
||||
|
||||
Color get _edge => switch (tone) {
|
||||
@@ -106,15 +108,25 @@ class DmCard extends StatelessWidget {
|
||||
boxShadow: _lifts ? (raised ? DmShadow.cardRaised : DmShadow.card) : null,
|
||||
),
|
||||
child: Container(
|
||||
// A tone that is not white keeps its edge: a crimson or washed card is
|
||||
// already separated from the canvas by its own colour, and a shadow
|
||||
// under a saturated fill reads as grime rather than as lift.
|
||||
foregroundDecoration: _lifts
|
||||
? null
|
||||
: BoxDecoration(
|
||||
borderRadius: radius,
|
||||
border: Border.all(color: _edge),
|
||||
),
|
||||
// ── Every card keeps its edge now ──
|
||||
//
|
||||
// A white card used to have none: the warm canvas underneath was doing
|
||||
// the separating, and a border on top of that contrast read as an
|
||||
// outlined box rather than a lifted surface.
|
||||
//
|
||||
// The page is white. A white card on it is invisible — measured, not
|
||||
// guessed: a scan across a card boundary on the Orders golden was
|
||||
// #FFFFFF from end to end, with the shadow contributing nothing the
|
||||
// eye could find. One of the two has to do the separating, and with
|
||||
// the page white it has to be the edge.
|
||||
//
|
||||
// The lift stays underneath it. Border plus a soft shadow is the iOS
|
||||
// and Revolut shape; it is not the borderless Airbnb one, and that is
|
||||
// the cost of a white page.
|
||||
foregroundDecoration: BoxDecoration(
|
||||
borderRadius: radius,
|
||||
border: Border.all(color: _edge),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: radius,
|
||||
child: Column(
|
||||
|
||||
Reference in New Issue
Block a user