Foundations
Materials
Three materials sit between the page and what floats over it. The scrim is shadow, so it stays dark in both themes. The frost is surface, so it inverts with the ground it blurs. And the panels are solid — a step off the canvas, not a tint of it.
Scrim
The layer behind every modal. A scrim is shadow, not surface, so it does not
invert: ink at 35% on light, black at 50% on dark. It crossfades on its own
curve (animate-scrim-in/-out) while the panel above it moves on the overlay
ease — splitting the two is what stops a scaling dialog from dragging its own
shadow up with it.
bg-scrim
<div className="fixed inset-0 bg-scrim" /> // behind every dialog
Frost
The frosted panel used by the tab bar, the popover triggers and the ranking
page's logo chip, spent as the blur-bg utility: a 14px backdrop blur under
the --frost tint. The tint inverts with the theme — the panel tints whatever
it blurs away, so it lightens a light page and darkens a dark one. Browsers
without backdrop-filter (WeChat's in-app browser is the target) fall back to
--frost-solid, the heavier opaque pill.
| Token | Light | Dark | Role |
|---|---|---|---|
--scrim | ink / 35% | black / 50% | The mask behind modals. |
--frost | #f8f9fa / 72% | black / 30% | The blur tint — blur-bg. |
--frost-solid | #f8f9fa / 85% | #202220 / 70% | The no-backdrop-filter fallback, and the mobile tab bar's heavier pill. |
blur-bg
<nav className="blur-bg rounded-full px-5 py-2">…</nav>
Panels
The elevated surfaces — dialogs, popovers, the composer's panels, the mention
list — are solid colours, not ink tints. They float above their own scrim, and
a translucent tint would show the page through. --popover is the menu plate;
--panel is the dialog ground, one step warmer in dark. Both carry
shadow-lg and the theme's hairline.
bg-popover
bg-panel
<div className="rounded-2xl bg-popover shadow-lg" /> <div className="rounded-2xl bg-panel shadow-lg" />