Vitest hoists vi.mock()/vi.hoisted() above all imports, so the
component import can sit with the other imports (import/first satisfied)
without the eslint-disable-next-line directives — the mock factories
only deref their refs at mount time. Honors the no-eslint-disable rule.
28/28 affected specs green.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The project's no-unused-vars only ignores all-underscore names (/^_+$/u);
`_bp` in the @vueuse/core useBreakpoints mock failed it. Latent since
Task 3 — masked because the whole-codebase `pnpm lint` stylish formatter
OOMs (RangeError on the legacy-code message volume) and emitted no
results. Scoped errors-only lint surfaced it. 21/21 specs still green.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CRITICAL: replace `lg:hidden` on PrimeVue Drawer with `v-if="isMobile"` so the
teleported portal/overlay is never created on desktop viewports regardless of
mobileOpen state. Replace useMediaQuery raw string in SidebarHeader with
useBreakpoints(breakpointsTailwind).smaller('lg') shared by both components.
Add desktop/mobile comments; adapt tests to useBreakpoints mock; add
Drawer-absent-on-desktop and aside w-16/w-64 width-class assertions (21 tests).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Ports crewli-starter's monolithic AppSidebar.vue into two typed production
components: SidebarHeader (the .brand block) and AppSidebar (composing
SidebarHeader + SidebarNav + WorkspaceSwitcher). AppSidebar renders a
permanent <aside> on desktop (lg+) and a PrimeVue Drawer on mobile, both
wired to useShellUiStore for collapse/mobile state.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>