fix: stack footer links vertically on mobile

Wrapped inline links produced a ragged two-line block with small tap targets.
Links now stack in a single column below sm and return to one row above it.

E2e asserts both directions: every link has a distinct y at 375px, and they
share a row at 1280px.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
isra el
2026-07-18 21:27:21 +03:00
parent 9cb1213efc
commit ffbbabdbd3
2 changed files with 37 additions and 1 deletions

View File

@@ -36,7 +36,9 @@ export default function Footer() {
</span>
</div>
<nav className='flex flex-wrap items-center justify-center gap-x-5 gap-y-2'>
{/* Stacked on mobile: wrapped inline links produced a ragged two-line
block that was hard to scan and gave small tap targets. */}
<nav className='flex w-full flex-col items-center gap-3 sm:w-auto sm:flex-row sm:flex-wrap sm:justify-center sm:gap-x-5 sm:gap-y-2'>
{links.map((link) => (
<Link
key={link.label}

View File

@@ -61,6 +61,40 @@ test.describe('app chrome (mocked API, no real backend)', () => {
).toBeLessThanOrEqual(tabBarBox!.y + 1)
})
test('mobile: footer links stack vertically', async ({ page, context }) => {
await page.setViewportSize({ width: 375, height: 800 })
await authenticate(context)
await mockApi(page)
await page.goto('/dashboard')
const links = page.locator('footer nav a')
const count = await links.count()
expect(count).toBeGreaterThan(2)
// Stacked means every link sits on its own row, so each y is distinct.
const ys: number[] = []
for (let i = 0; i < count; i += 1) {
const box = await links.nth(i).boundingBox()
expect(box).not.toBeNull()
ys.push(Math.round(box!.y))
}
expect(new Set(ys).size, 'each footer link should be on its own row').toBe(
count
)
})
test('desktop: footer links sit on one row', async ({ page, context }) => {
await page.setViewportSize({ width: 1280, height: 900 })
await authenticate(context)
await mockApi(page)
await page.goto('/dashboard')
const links = page.locator('footer nav a')
const first = await links.first().boundingBox()
const last = await links.last().boundingBox()
expect(Math.abs(first!.y - last!.y)).toBeLessThan(8)
})
test('top bar is reduced to brand and account', async ({ page, context }) => {
await authenticate(context)
await mockApi(page)