diff --git a/tests/unit/vyndrParityQA.test.js b/tests/unit/vyndrParityQA.test.js index 6ba1fcf..8a20b49 100644 --- a/tests/unit/vyndrParityQA.test.js +++ b/tests/unit/vyndrParityQA.test.js @@ -177,3 +177,31 @@ describe('M1 — mobile foundation is wired (structural, not visual)', () => { expect(css).toMatch(/@media\s*\(max-width:\s*767px\)\s*\{[^]*?html,\s*body\s*\{[^}]*overflow-x:\s*hidden/); }); }); + +// ── M4 — structural mobile locks (design completion train) ────────────── +describe('M4 — mobile structural rules locked (source, not visual)', () => { + const css = read('app/globals.css'); + + it('the flat EDGE BOARD is the mobile board; game cards are desktop-only', () => { + // Design screen 01: <768px shows the flat edge-ranked board, ≥768px keeps + // the game-grouped cards. + expect(css).toMatch(/\.edge-board-mobile\s*\{\s*display:\s*none/); + expect(css).toMatch(/@media\s*\(max-width:\s*767px\)[^]*?\.edge-board-mobile\s*\{\s*display:\s*block/); + expect(css).toMatch(/\.edge-board-desktop\s*\{\s*display:\s*none\s*!important/); + const slate = read('components/Slate.tsx'); + expect(slate).toMatch(/MobileEdgeBoard/); + expect(slate).toMatch(/flattenToEdgeBoard/); + }); + + it('the mobile edge board renders matchup chips + tier grade + one hero edge%', () => { + const b = read('components/vyndr/MobileEdgeBoard.tsx'); + expect(b).toMatch(/TeamChip/); // Rev 3 matchup chips + expect(b).toMatch(/GradeBadge/); // tier-colored grade + expect(b).toMatch(/var\(--miss\)/); // negative edge = red by sign + expect(b).toMatch(/rampOpacity/); // Design's ranked opacity ramp + }); + + it('document still never scrolls sideways on phones (overflow contained)', () => { + expect(css).toMatch(/@media\s*\(max-width:\s*767px\)\s*\{[^]*?html,\s*body\s*\{[^}]*overflow-x:\s*hidden/); + }); +});