VisualContentSeeder::class, '--force' => true]); }); it('keeps the full home cadence accessible and contained at both viewports', function (): void { foreach ([[1440, 1000], [390, 844]] as [$width, $height]) { $page = $this->visit('/', [ 'reducedMotion' => 'reduce', ])->resize($width, $height); $page->assertNoAccessibilityIssues(1); $layout = $page->script(<<<'JS' () => { const chapters = Array.from(document.querySelectorAll('.home-chapter')); const folios = Array.from(document.querySelectorAll('[data-home-folio]')); const clippedValues = new Set(['clip', 'hidden']); const textNodes = Array.from(document.querySelectorAll( '.home-chapters h1, .home-chapters h2, .home-chapters h3, .home-chapters p, .home-chapters a, .home-chapters span' )); return { horizontalOverflow: document.documentElement.scrollWidth > window.innerWidth, overlappingChapters: chapters.slice(1).some((chapter, index) => { const previous = chapters[index].getBoundingClientRect(); const current = chapter.getBoundingClientRect(); return current.top < previous.bottom - 1; }), overflowingFolios: folios.filter((folio) => { const rect = folio.getBoundingClientRect(); return rect.left < -1 || rect.right > window.innerWidth + 1; }).length, clippedText: textNodes.filter((node) => { const style = getComputedStyle(node); const clippedX = clippedValues.has(style.overflowX) && node.scrollWidth > node.clientWidth + 1; const clippedY = clippedValues.has(style.overflowY) && node.scrollHeight > node.clientHeight + 1; return clippedX || clippedY; }).length, }; } JS); expect($layout)->toBe([ 'horizontalOverflow' => false, 'overlappingChapters' => false, 'overflowingFolios' => 0, 'clippedText' => 0, ]); } });