From ee43e5334fd011542d1b6612645e77cf9f53f742 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sun, 1 Nov 2026 09:51:25 -0800 Subject: [PATCH] fix(pods): 44px targets for the phone Pods bar At 390 the Pods title bar's controls measured 28x24 (light and dark), 28x28 (search) and 32x32 (new pod). The icon keys are now 44x44, New pod overrides its own 32px flex-basis, and the theme buttons are 44x40 with an ::after that adds the 2px the pill's padding takes back, inside each button's own column so the two never overlap. A layout invariant guards all four rules, each reverse-verified. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015AKgpMD6Qh13f7fj6mbGT3 --- .../v2/__tests__/v2-layout-invariants.test.ts | 14 +++++++++++ frontend/src/v2/v2.css | 25 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/frontend/src/v2/__tests__/v2-layout-invariants.test.ts b/frontend/src/v2/__tests__/v2-layout-invariants.test.ts index 88844d91a..96fc06ef7 100644 --- a/frontend/src/v2/__tests__/v2-layout-invariants.test.ts +++ b/frontend/src/v2/__tests__/v2-layout-invariants.test.ts @@ -565,6 +565,20 @@ describe('v2 layout invariants (CSS rule presence)', () => { expect(ruleBody(v2, '.v2-pods__page-title')).toContain('font: 800 21px/1 var(--v2-font-display, var(--v2-font))'); }); + test('the phone pods bar gives each control a 44px target', () => { + const icon = topLevelRuleBody(v2, '.v2-pods-aside--page .v2-pods__bar .v2p-ib'); + expect(icon).toContain('width: 44px'); + expect(icon).toContain('height: 44px'); + // .v2-pods__new sets flex: 0 0 32px; without this the New pod key stays 32px wide. + expect(topLevelRuleBody(v2, '.v2-root .v2-pods-aside--page .v2-pods__bar button.v2-pods__new')).toContain('flex-basis: 44px'); + const theme = topLevelRuleBody(v2, '.v2-pods-aside--page .v2-pods__bar .seg.v2-theme-seg button'); + expect(theme).toContain('position: relative'); + expect(theme).toContain('width: 44px'); + expect(theme).toContain('height: 40px'); + // The 2px the seg's padding takes back comes from ::after, inside the button's own column. + expect(topLevelRuleBody(v2, '.v2-pods-aside--page .v2-pods__bar .seg.v2-theme-seg button::after')).toContain('inset: -2px 0'); + }); + test('pod search shortcut hint hides on narrow and touch-only screens', () => { const hideHint = mediaAt(v2, '@media (max-width: 760px), (hover: none) and (pointer: coarse) {'); expect(hideHint).not.toBe(''); diff --git a/frontend/src/v2/v2.css b/frontend/src/v2/v2.css index c47ebe973..924fa3384 100644 --- a/frontend/src/v2/v2.css +++ b/frontend/src/v2/v2.css @@ -4676,6 +4676,31 @@ body.modern-ui.v2-canvas { white-space: nowrap; } +/* The 390 bar's controls are 44px touch targets. The frame draws them at 34px, + so they go to 44px at this width. The theme buttons keep their pill and reach + 44px tall through ::after, which stays inside each button's own column. */ +.v2-pods-aside--page .v2-pods__bar .v2p-ib { + width: 44px; + height: 44px; +} + +/* New pod carries its own flex-basis (.v2-pods__new, 32px); the bar overrides it. */ +.v2-root .v2-pods-aside--page .v2-pods__bar button.v2-pods__new { + flex-basis: 44px; +} + +.v2-pods-aside--page .v2-pods__bar .seg.v2-theme-seg button { + position: relative; + width: 44px; + height: 40px; +} + +.v2-pods-aside--page .v2-pods__bar .seg.v2-theme-seg button::after { + content: ''; + position: absolute; + inset: -2px 0; +} + .v2-pods-aside--page .v2-pods__body { display: flex; min-height: 0;