Skip to content

mac: the header, px for px against the lab - #300

Merged
stupart merged 1 commit into
mainfrom
feat/header-anatomy
Sep 16, 2026
Merged

stupart merged 1 commit into
mainfrom
feat/header-anatomy

Conversation

@stupart

@stupart stupart commented Sep 16, 2026

Copy link
Copy Markdown
Owner

The header's three fully-sourced corrections, each quoted to the lab selector it came from.

was now lab
session title 12.5 medium 14 semibold, -0.01em .ttl{font:600 14px;letter-spacing:-.01em}
context used / limit, always 87% context, at ≥85% only .ctxwarn{font-size:12px;color:var(--listening)} + §5
view switch 3 loose buttons one .seg track .seg{padding:2px;border-radius:8px;background:var(--fill);gap:1px}

The selected segment is marked by --fillSel alone: .seg button.on also asks for box-shadow:var(--shRaised), but that variable is defined nowhere in the lab, so it renders nothing in the prototype either.

Two deletions fall out of the threshold change: the meter's third status colour (unreachable once it is not drawn below 85%) and PerspectiveOption's old padding/height, which would fight the fixed 30×24 frame.

Not in this slice, on purpose: the breadcrumb and the state-with-text chip. Both need the lab's VIS state vocabulary, which the app does not have — and a px pass is the wrong place to invent one.

Gate: bun test 2309/0 · tsc clean · swift test 131/0 · Mac + iOS xcodebuild both green (CI builds neither app) · 9 mutations, 9 killed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE

Three corrections, each taken from `workspace-lab.html`'s own CSS rather than
§3's prose — the prototype is what "matches the mockups" means.

The session title is the line that says what you are looking at, and it was
12.5 medium: a size the header's own meta text could match. `.ttl{font:600
14px;letter-spacing:-.01em}`.

Context pressure becomes `.ctxwarn` — a percentage, not a running token tally,
and drawn only at 85% and above (§5: "87% context"). Below that the header
says nothing about it at all, which is Tyler's own complaint ("a lot of
importance to a not super important piece of data") carried further than
colour alone could carry it. `used / limit` survives where it is asked for,
in the tooltip and to VoiceOver. The third status colour went with the rows
the meter used to sit on, so the branch that painted it is gone.

The view switch becomes `.seg`: one track on `--fill` at 2pt padding, 8pt
radius and 1pt gaps, each segment 30x24 at radius 6, the selected one marked
by `--fillSel` and nothing else. Three loose buttons read as three unrelated
controls; one track with a filled position reads as one control that knows
where it is. `.seg button.on` also asks for `box-shadow:var(--shRaised)`, a
variable defined nowhere in the lab and therefore rendering nothing — so the
fill is the whole mark, exactly as the prototype shows it.

The breadcrumb and the state-text chip are deliberately NOT here: they need a
state vocabulary the app does not have (the lab's `VIS`), and a px pass is the
wrong place to invent one.

Gated: bun test 2309/0, tsc clean, swift test 131/0, Mac and iOS both build
(CI builds neither). Nine mutations across all three corrections, nine killed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE
@stupart
stupart merged commit 8d7aba6 into main Sep 16, 2026
2 checks passed
@stupart
stupart deleted the feat/header-anatomy branch September 16, 2026 21:09
@stupart

stupart commented Sep 16, 2026

Copy link
Copy Markdown
Owner Author

Correction, found while sourcing the next slice: --shRaised is defined in the lab, and this PR's claim that it isn't is wrong.

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) — --shRaised:0 0 0 .5px rgba(255,255,255,.08),0 1px 2px rgba(0,0,0,.4)

My earlier grep missed it because the lab defines its whole palette on one minified line, and I searched for the variable at the start of a line. So .seg button.on does render a ring plus a 1px/2px drop, and what shipped here — the selected segment marked by fill alone — is missing it. Worse, the guard expect(segment).not.toContain("conchElevation") now pins the mistake in place.

Being fixed in the next slice alongside the --shPanel divergence, which the same reading turned up: the stage panel's light drop should be rgba(0,0,0,.04) where .raised gives .1, and its dark drop should not exist at all where ElevationModifier doubles it to .2.

The three px corrections in this PR (title, context meter, seg geometry) are unaffected — they were sourced from the CSS directly.

stupart added a commit that referenced this pull request Sep 16, 2026
`--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.


Claude-Session: https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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