diff --git a/docs/src/components/CustomFooter.astro b/docs/src/components/CustomFooter.astro index 72133076a14..0f9ac654ea1 100644 --- a/docs/src/components/CustomFooter.astro +++ b/docs/src/components/CustomFooter.astro @@ -124,6 +124,20 @@ const heartIcon = octicons.heart.toSVG({ width: 14, height: 14 }); .footer-terms { text-align: center; } + + /* WCAG 2.5.5: Minimum 44×44px touch target for footer links on mobile */ + .community-feedback a, + .agent-links a, + .footer-terms a { + min-height: 44px; + display: inline-flex; + align-items: center; + padding: 0.25rem 0.5rem; + } + + .agent-links { + gap: 0.25rem; + } } .heart-icon { diff --git a/docs/src/components/ThemeToggle.astro b/docs/src/components/ThemeToggle.astro index 510998204e1..9ff6987771a 100644 --- a/docs/src/components/ThemeToggle.astro +++ b/docs/src/components/ThemeToggle.astro @@ -122,6 +122,12 @@ const autoIcon = octicons['device-desktop'].toSVG({ width: 16, height: 16 }); /* Mobile-specific: Ensure minimum 44x44px touch target for WCAG 2.1 Level AAA */ @media (max-width: 768px) { + .theme-label { + min-height: 44px; + display: inline-flex; + align-items: center; + } + .icon-wrapper { width: 44px; height: 44px; diff --git a/docs/src/styles/custom.css b/docs/src/styles/custom.css index 8cd89a313b7..2ec96aea0d0 100644 --- a/docs/src/styles/custom.css +++ b/docs/src/styles/custom.css @@ -1635,6 +1635,39 @@ main, } } +/* === W2: Lower sidebar breakpoint to 768px for tablet support === */ +/* Starlight default is 50rem (800px). At 48rem (768px) the sidebar becomes persistent */ +/* so iPad (768×1024) and iPad Pro 11 (834×1194) show a sidebar instead of hamburger menu. */ +@media (min-width: 48rem) { + /* Offset main content to make room for the persistent sidebar */ + html[data-has-sidebar] { + --sl-content-inline-start: var(--sl-sidebar-width); + } + + /* Make the sidebar pane always visible (not overlay) */ + .sidebar-pane { + --sl-sidebar-visibility: visible; + width: var(--sl-sidebar-width) !important; + background-color: var(--sl-color-bg-sidebar) !important; + border-inline-end: 1px solid var(--sl-color-hairline-shade) !important; + } + + /* Remove the extra header padding that was reserved for the hamburger button */ + [data-has-sidebar] .header { + padding-inline-end: var(--sl-nav-pad-x) !important; + } + + /* Hide the mobile hamburger toggle since the sidebar is now persistent */ + starlight-menu-button button { + display: none !important; + } + + /* Restore body scroll when sidebar becomes persistent (was locked when menu was open) */ + [data-mobile-menu-expanded] { + overflow: auto !important; + } +} + /* Mobile-specific: Additional touch target improvements for remaining elements */ @media (max-width: 768px) { /* Skip to content link - accessibility feature */ diff --git a/docs/tests/mobile-responsive.spec.ts b/docs/tests/mobile-responsive.spec.ts index a427f6afccc..8bfd36c8169 100644 --- a/docs/tests/mobile-responsive.spec.ts +++ b/docs/tests/mobile-responsive.spec.ts @@ -3,7 +3,9 @@ import { test, expect } from '@playwright/test'; test.describe('Mobile and Responsive Layout', () => { const formFactors = [ { name: 'iPhone 16 (Mobile)', width: 393, height: 852 }, - { name: 'Tablet 4:3 (iPad)', width: 1024, height: 768 }, + { name: 'iPad (768px)', width: 768, height: 1024 }, + { name: 'iPad Pro 11 (834px)', width: 834, height: 1194 }, + { name: 'iPad Landscape (1024px)', width: 1024, height: 768 }, { name: 'Desktop Portrait', width: 1080, height: 1920 }, { name: 'Desktop Landscape', width: 1920, height: 1080 }, ]; @@ -46,7 +48,7 @@ test.describe('Mobile and Responsive Layout', () => { } test('should have proper content spacing on mobile', async ({ page }) => { - if (formFactor.width <= 768) { + if (formFactor.width < 768) { await page.goto('/gh-aw/introduction/overview/'); await page.waitForLoadState('networkidle'); @@ -54,11 +56,22 @@ test.describe('Mobile and Responsive Layout', () => { const contentPanel = page.locator('.content-panel').first(); await expect(contentPanel).toBeVisible(); - // Sidebar should be hidden on mobile + // Sidebar should be hidden on mobile (below 768px) const sidebar = page.locator('.sidebar'); await expect(sidebar).not.toBeVisible(); } }); + + test('should show persistent sidebar on tablet (WCAG W2)', async ({ page }) => { + if (formFactor.width >= 768) { + await page.goto('/gh-aw/introduction/overview/'); + await page.waitForLoadState('networkidle'); + + // Sidebar should be persistently visible on tablet and desktop (768px+) + const sidebar = page.locator('.sidebar'); + await expect(sidebar).toBeVisible(); + } + }); }); } });