Skip to content

design: the four shadows, from the lab's own variables - #301

Merged
stupart merged 1 commit into
mainfrom
feat/shadow-values
Sep 16, 2026
Merged

stupart merged 1 commit into
mainfrom
feat/shadow-values

Conversation

@stupart

@stupart stupart commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Fixes a mistake this session shipped in #300, and the divergence that finding it uncovered.

--shRaised is defined; #300 said it wasn't

workspace-lab.html:17 — --shRaised:0 0 0 .5px rgba(0,0,0,.06),0 1px 2px rgba(0,0,0,.14)
workspace-lab.html:20 — dark: 0 0 0 .5px rgba(255,255,255,.08),0 1px 2px rgba(0,0,0,.4)

The grep behind the "undefined" claim searched for the variable at the start of a line; the lab's :root is minified onto one. So the selected segment shipped with no ring and no drop, and a guard asserted the absence. The guard is inverted, not deleted.

The table, as the lab actually defines it

light dark was
--shPanel r1.5 y1 .04 ring only, no drop .raised → .1, doubled to .2 on dark
--shRaised r1 y1 .14 r1 y1 .4 r1.5 y1 .1, doubled to .2
--shFloat r14 y10 .24 r14 y10 .7 .22, doubled to .44
--shOver r32 y24 .32 r32 y24 .75 r24 y18 .26, doubled to .52

CSS blur is twice SwiftUI's shadow radius. ElevationModifier's rule — "dark grounds swallow a shadow, so it doubles there" — was wrong in both directions: it painted a shadow on dark where the lab draws none, and undershot every one the lab keeps. Each level carries its own dark value now, and the stage panel moves to a panel level instead of borrowing a selected segment's shadow (the #299 divergence).

Tests

Elevation had no coverage at all. Seven tests now, including a pixel test of the modifier: every value test passes with the doubling rule still in place, so the values alone could not catch its return. That test's control assertion fails if the harness renders no shadow, so it cannot pass by measuring nothing.

Gate: bun test 2309/0 · tsc clean · swift test 138/0 · Mac + iOS both build (CI builds neither) · 12 mutations, 12 killed — including both modifier reverts.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE

`--shRaised` IS defined in the lab — line 17, and line 20 for dark. The grep
behind the claim that it wasn't looked for the variable at the start of a line,
and the lab's `:root` is minified onto one. So #300 shipped the selected
segment flat AND added a guard asserting it stay that way. Both are corrected
here; the guard is inverted rather than deleted, so the mistake cannot return
quietly.

Reading the whole table turned up the second divergence, which #299 introduced:
the stage panel borrowed `.raised`, and `ElevationModifier` doubled every
shadow on dark. The lab's `--shPanel` keeps its ring and drops its shadow
outright on dark — something no blanket rule can express.

Each level now carries the lab's own pair, and `panel` becomes its own level:

                light            dark
    --shPanel   r1.5 y1  .04     ring only, no drop
    --shRaised  r1   y1  .14     r1   y1  .4
    --shFloat   r14  y10 .24     r14  y10 .7
    --shOver    r32  y24 .32     r32  y24 .75

CSS blur is twice SwiftUI's shadow radius. Two more were wrong on the way past:
`.overlay` sat at r24/y18/.26 against the lab's r32/y24/.32, and `.floating`
computed .44 on dark where the lab asks .7.

Elevation had no test coverage whatsoever. It has seven tests now, including a
pixel test of the modifier itself — every value test still passes with the
doubling rule in place, so the values alone could never catch its return.

The segment's hover fill is recorded as the app's own: the lab gives
`.seg button` no `:hover` rule at all.

Gated: bun test 2309/0, tsc clean, swift test 138/0, Mac and iOS both build
(CI builds neither). Twelve mutations across the tokens, the modifier and the
source guards; twelve killed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE
@stupart
stupart merged commit a834c22 into main Sep 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant