fix(design-system): compose rim + elevation tokens correctly (panels actually have chrome now) #99

Merged
varutasu merged 1 commit from fix-glass-panel-rim-shadow-composition into main 2026-06-03 23:49:06 -04:00

View file

@ -439,31 +439,47 @@ body {
from Tailwind (the class itself doesn't set border-radius from Tailwind (the class itself doesn't set border-radius
because consumers vary between rounded-xl and rounded-2xl). because consumers vary between rounded-xl and rounded-2xl).
============================================================ */ ============================================================ */
/* IMPORTANT backdrop-filter quirks with Next.js 16's Lightning CSS: /* IMPORTANT composing rim + elevation tokens correctly.
The --rim-light-outer / --rim-light-inner / --elevation-* tokens are
COMPLETE box-shadow declarations (each contains offset/spread/color or
the `inset` keyword), not raw color values. They are designed to be
*chained into a single box-shadow*, exactly the way <GlassSurface>'s
`boxShadow: shadowParts.join(', ')` composes them. Do NOT use
`border: 1px solid var(--rim-light-outer)` that parses
`border-width` from the first token of the shadow string ("0"), which
yields a 0px border. And do NOT wrap --rim-light-inner in another
`inset 0 1px 0` prefix the token already contains its own `inset`
keyword, so wrapping produces invalid syntax that the browser drops
the entire box-shadow declaration for. PR #98 had both mistakes,
which is why the panels in PR #97/#98 had neither visible border nor
drop shadow despite the backdrop-filter being correct.
Backdrop-filter quirks with Next.js 16's Lightning CSS (also relevant):
1) `backdrop-filter: blur(var(--X)) saturate(var(--Y))` is silently 1) `backdrop-filter: blur(var(--X)) saturate(var(--Y))` is silently
stripped from the compiled CSS (same root cause that emptied stripped (var() inside function args breaks the optimizer). Use
`.mobile-nav-backdrop` in production). Use LITERAL values. LITERAL values here. Tokens stay in :root for the <GlassSurface>
2) Writing both `backdrop-filter` and `-webkit-backdrop-filter` with JSX primitive which sets backdropFilter via inline style.
identical values triggers Lightning CSS's de-dup; it keeps only the 2) Writing both `backdrop-filter` AND `-webkit-backdrop-filter` with
`-webkit-` form which Chrome/Edge/Firefox ignore. Write only the identical values triggers Lightning CSS's buggy de-dup; it keeps
unprefixed `backdrop-filter` and let Lightning CSS's autoprefixer only the `-webkit-` form which modern browsers ignore. Write only
add the vendor prefix per browserslist (it does for ios_saf <18). the unprefixed form; Lightning CSS's autoprefixer adds the prefix
If the blur radii ever need to change, change them here AND in the per browserslist (ios_saf <18 still needs it). */
matching --glass-blur-* tokens (kept for `<GlassSurface>` JSX consumers
which set `backdropFilter` via inline style those are unaffected by
the Lightning CSS optimizer). */
.glass-panel { .glass-panel {
background-color: var(--glass-surface-mid); background: var(--glass-surface-mid);
backdrop-filter: blur(12px) saturate(180%); backdrop-filter: blur(12px) saturate(180%);
border: 1px solid var(--rim-light-outer); box-shadow:
box-shadow: var(--elevation-ambient), inset 0 1px 0 var(--rim-light-inner); var(--rim-light-inner),
var(--rim-light-outer),
var(--elevation-ambient);
} }
.glass-panel-strong { .glass-panel-strong {
background-color: var(--glass-surface-high); background: var(--glass-surface-high);
backdrop-filter: blur(20px) saturate(180%); backdrop-filter: blur(20px) saturate(180%);
border: 1px solid var(--rim-light-outer); box-shadow:
box-shadow: var(--elevation-pronounced), inset 0 1px 0 var(--rim-light-inner); var(--rim-light-inner),
var(--rim-light-outer),
var(--elevation-pronounced);
} }
/* Gradient text effects Deck Hearth warm palette only. /* Gradient text effects Deck Hearth warm palette only.