fix(design-system): compose rim + elevation tokens correctly (panels actually have chrome now) #99
No reviewers
Labels
No labels
agent-context-drift
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: rstillwell/deckhearth#99
Loading…
Reference in a new issue
No description provided.
Delete branch "fix-glass-panel-rim-shadow-composition"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why this exists
After PR #98 ("backdrop-filter now applies"), user reported
deckhearth.com/dashboardstill showed flat-looking panels. CDP diagnostic on the live page found the smoking gun:```
panelComputed: {
bg: "rgba(254, 252, 248, 0.68)", // OK
border: "rgb(45, 24, 16) none 0px", // BROKEN — border-width is 0
boxShadow: "none" // BROKEN — entire declaration dropped
}
```
Backdrop-filter was finally being applied, but the panels had no border and no shadow — so they looked like flat color swatches sitting on a same-hue page background.
Root cause
I misused the rim + elevation tokens. They are complete box-shadow declarations, not raw color values:
```css
--rim-light-outer: 0 0 0 1px #2d181014; /* 1px-spread ring /
--rim-light-inner: inset 0 1px 0 0 #ffffffa6; / inset white highlight /
--elevation-ambient: 0 4px 12px -2px #2d181014,
0 2px 4px -1px #2d18100a; / 2-layer drop shadow */
```
In PRs #97/#98 I wrote:
```css
.glass-panel {
border: 1px solid var(--rim-light-outer);
box-shadow: var(--elevation-ambient), inset 0 1px 0 var(--rim-light-inner);
}
```
Two mistakes:
border: 1px solid var(--rim-light-outer)— the var expands to0 0 0 1px #2d181014. CSS's border shorthand parses the first whitespace-separated token of the value asborder-width→"0"→ 0px border. Result: no border.inset 0 1px 0 var(--rim-light-inner)— the var already starts withinset, so expansion givesinset 0 1px 0 inset 0 1px 0 0 #ffffffa6. Twoinsetkeywords → invalid shadow layer → browser drops the entire box-shadow declaration (per CSS spec, one bad layer kills the whole property). Result:boxShadow: none.Fix
The tokens are designed to be chained into a single
box-shadow, exactly the way `` composes them at `components/ui/GlassSurface.js` lines 5–15:```js
const shadowParts = [
'var(--rim-light-inner)',
'var(--rim-light-outer)',
'var(--elevation-ambient)',
];
// → boxShadow: shadowParts.join(', ')
```
So this PR replaces the broken `border` + nested-inset pattern with a clean chained shadow:
```css
.glass-panel {
background: var(--glass-surface-mid);
backdrop-filter: blur(12px) saturate(180%);
box-shadow:
var(--rim-light-inner),
var(--rim-light-outer),
var(--elevation-ambient);
}
```
After variable substitution this becomes a valid 4-layer shadow:
i.e. an actual glass card with visible chrome.
Maintainer comment added in CSS
A 25-line block comment above the two utility classes documents:
The next agent (human or AI) reading the CSS will be told exactly which two mistakes to NOT make.
Tests
Test plan
Made with Cursor
The latest updates on your projects. Learn more about Vercel for GitHub.
Pipeline Health
Build + CI gates
Build runs on Vercel; this CI runs lint and schema-map drift only (no duplicate build).
Role reports
See individual comments above for details. This rollup updates automatically.
Visual Diff
Screenshots and diffs uploaded as artifacts: view run
If intentional changes: update snapshots locally with
npx playwright test --project=visual --update-snapshotsand commit.