Flat
The default. A step lighter than the page, no border, no shadow.
Two shadow levels only. A bounded surface reads by being a step lighter than what's behind it, not by a border around its edge; shadow is reserved for the one floating layer in a view.
This system’s own rule: no border marks the edge of a bounded surface. A
flat Card is the default
everywhere — --gl-color-surface-card is one neutral step lighter than
--gl-color-surface-page around it, and that tonal step is what reads as
“a card,” not an outline. Shadow is the exception, not the baseline.
Hairlines have not disappeared from the system — a CardRow still divides from its neighbor on one, a table still rules its rows, an underline tab still sits on one — they just no longer wrap a whole surface. A divider inside a card; never a border around one.
Barely-there separation — a Switch thumb, a focused Input.
The one floating layer in a view. Apply it to at most one element on screen at a time.
The default. A step lighter than the page, no border, no shadow.
shadow-float. Reserved for one element per view — a Dialog, a Toast.
<article class="card">
<div class="card-body">
<h3>Flat</h3>
<p>The default. A step lighter than the page, no border, no shadow.</p>
</div>
</article>
<article class="card" data-elevated>
<div class="card-body">
<h3>Elevated</h3>
<p>shadow-float. Reserved for one element per view — a Dialog, a Toast.</p>
</div>
</article>
Shadows barely register on a near-black surface. The dark theme leans on
surface lightness instead — --gl-color-surface-card is one neutral step
lighter than --gl-color-surface-page, same as in light mode. The shadow
tokens still apply; they simply stop being the primary signal.
--gl-shadow-float on screen. If two things both claim to
be the topmost layer, neither is.opacity, or do not animate it at all.