style(layout): sidebar brand-square symmetry + WorkspaceSwitcher trigger polish

Plan 2.5 P6 follow-up. Closes two desktop shell-parity gaps from P6
manual smoke against crewli-starter SoT:

- Sidebar logo decoupled from the collapse toggle. Expanded layout is
  now justify-between (brand group left, collapse chevron right) and
  collapsed layout is justify-center with the logo alone. The expand
  affordance becomes a small absolute-positioned circular button at
  the rail's right edge — solid background + border so the slight
  overlap with the centred logo reads as a tucked-in chip rather than
  a collision. Toggling collapsed no longer shifts the logo.
- Brand square (SidebarHeader logo) and workspace avatar
  (WorkspaceSwitcher trigger) unified to the same rounded square
  (h-8 w-8 rounded-xl). Existing sizes were already consistent at
  32px — radius bumped from rounded-lg (8px) / var(--p-border-radius)
  (~6px) to rounded-xl (12px) per the design direction. Collapsed
  rail now reads as a vertical mirror: brand square at the top,
  avatar square at the bottom, bracketing the nav icons.
- WorkspaceSwitcher trigger restyled: rounded-xl (was the sharper
  var-radius), p-2 (was px-[10px] py-[8px]), hover background. The
  collapsed-variant gating of name + chevron is unchanged from P5.

Edge-mounted overhang past the rail edge was not possible: the aside
carries `overflow-hidden` (intentional, for the w-64 ⇄ w-16 width
transition) which clips anything past the rail edge. The tucked-chip
pattern (24px circle at end-0, solid bg) is the visual compromise —
the affordance stays inside the rail, discoverable, and visually
decoupled from the logo.

Desktop only. Mobile drawer chrome (logo placement, drawer X button,
missing switcher) tracked separately as MOBILE-SHELL-PARITY.

Tests:
- +2 WorkspaceSwitcher.spec.ts: trigger uses rounded-xl; collapsed
  trigger renders avatar only (hides .meta).
- +1 SidebarHeader.spec.ts: collapsed row hides the .brand-name
  wordmark and toggles to justify-center (logo-stays-centred lock).

Suite delta: 558 → 561 (+3). vue-tsc clean. Scoped ESLint clean
(0 errors, pre-existing warnings only).

Manual smoke pending Bert: collapse the rail, verify logo stays put
and the expand chip appears at the right edge; verify the trigger
shows rounded corners + hover bg; verify the collapsed avatar
mirrors the brand square size/radius.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-21 00:15:34 +02:00
parent 31a851e6e0
commit 8e16651232
4 changed files with 120 additions and 53 deletions

View File

@@ -193,4 +193,26 @@ describe('SidebarHeader', () => {
expect(btn.attributes('aria-label')).toBe('Collapse sidebar')
})
// P6-followup-styling: when collapsed, the brand-name (wordmark) is
// hidden and the row centres the logo. The expand button is a
// separate absolute-positioned sibling — its presence must not push
// the logo off-centre. This spec locks the "logo stays centred"
// contract by asserting the row's flex alignment + wordmark absence.
it('collapsed: hides the Crewli wordmark and centres the row', async () => {
const wrapper = mountHeader()
const shell = useShellUiStore()
shell.sidebarCollapsed = true
await wrapper.vm.$nextTick()
expect(wrapper.find('.brand-name').exists()).toBe(false)
expect(wrapper.text()).not.toContain('Crewli')
// The header row toggles to justify-center when collapsed.
const row = wrapper.find('div')
expect(row.classes()).toContain('justify-center')
})
})