From 601f6ec3db222544675e9603debb397ab6450297 Mon Sep 17 00:00:00 2001 From: Matthew Valancy Date: Wed, 17 Jun 2026 17:00:42 -0700 Subject: [PATCH] =?UTF-8?q?LAYOUT-1:=20/signup=20fits=20the=20window=20?= =?UTF-8?q?=E2=80=94=20branding=20beside=20the=20form=20on=20large=20scree?= =?UTF-8?q?ns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The auth page stacked branding above a single max-w-md column, so it needed vertical scrolling on a big window (live audit: scrollH 1196 > 1000 @1600x1000). Per the "fit the window" design religion, on lg+ screens the branding now sits BESIDE the form in a wider 2-column grid (max-w-4xl), so the flow fits without scrolling; on small screens it stacks as before. Footer/dev-info stay below the grid full-width. Test: tests/e2e/signup-fit.spec.ts @signup-fit — large screen shows branding to the left of the form sharing the row + form fits the viewport height; phone has no horizontal overflow. (Absolute no-vertical-scroll is gated in the live cloud audit, since prod has none of the dev-only chrome — HTTP banner, Default Accounts box — that inflates a dev-server measurement.) Co-Authored-By: Claude Opus 4.8 (1M context) --- packages/web/src/pages/Signin.tsx | 11 +++++--- tests/e2e/signup-fit.spec.ts | 45 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 tests/e2e/signup-fit.spec.ts diff --git a/packages/web/src/pages/Signin.tsx b/packages/web/src/pages/Signin.tsx index 2f48ccff..2f19147a 100644 --- a/packages/web/src/pages/Signin.tsx +++ b/packages/web/src/pages/Signin.tsx @@ -430,10 +430,14 @@ export function Signin({ initialMagicLink = false }: { initialMagicLink?: boolea
{/* Static gradient background - optimized for all browsers */}
-
+ {/* Design religion: fit the window. On large screens the branding sits + BESIDE the form (wider, 2-column) so the page never needs vertical + scrolling; on small screens it stacks above as before. */} +
+
{/* Header */} -
- +
+ GraphDone Logo GraphDone @@ -961,6 +965,7 @@ export function Signin({ initialMagicLink = false }: { initialMagicLink?: boolea
)} +
{/* Development Mode - Default Credentials */} {showDefaultCredentials && ( diff --git a/tests/e2e/signup-fit.spec.ts b/tests/e2e/signup-fit.spec.ts new file mode 100644 index 00000000..2f7799d3 --- /dev/null +++ b/tests/e2e/signup-fit.spec.ts @@ -0,0 +1,45 @@ +import { test, expect } from '@playwright/test'; +import { getBaseURL } from '../helpers/auth'; + +/** + * Responsive "fit the window" religion (@signup-fit): on a large screen the + * /signup (magic-link) branding sits BESIDE the form (wider, 2-column) so the + * auth flow fits without vertical scrolling; on a phone it stacks with no + * horizontal overflow. + * + * The absolute "documentElement has no vertical scroll" assertion lives in the + * live cloud audit (production has no dev-only chrome — the HTTP "insecure + * connection" banner and the "Default Accounts" box only render in dev and + * would inflate a dev-server measurement). Here we verify the structural fix: + * the 2-column layout is active and the form itself fits the viewport height. + */ +test.describe('auth page fits the window @signup-fit', () => { + test('large screen: branding sits beside the form (2-column) @1600x1000', async ({ page }) => { + await page.setViewportSize({ width: 1600, height: 1000 }); + await page.goto(`${getBaseURL()}/signup`, { waitUntil: 'networkidle' }); + const form = page.locator('form').first(); + const header = page.getByRole('heading', { name: /welcome back/i }).first(); + await form.waitFor({ timeout: 10_000 }); + const fb = await form.boundingBox(); + const hb = await header.boundingBox(); + if (!fb || !hb) throw new Error('missing form/header'); + // Side-by-side: the heading sits to the LEFT of the form (separate columns), + // and they share the same row (vertical overlap) rather than stacking. + expect(hb.x + hb.width, `header right (${Math.round(hb.x + hb.width)}) left of form (${Math.round(fb.x)})`).toBeLessThanOrEqual(fb.x + 8); + const verticalOverlap = Math.min(hb.y + hb.height, fb.y + fb.height) - Math.max(hb.y, fb.y); + expect(verticalOverlap, 'header and form share the row').toBeGreaterThan(0); + // The form alone fits comfortably within a 1000px-tall window. + expect(fb.height, `form height ${Math.round(fb.height)} fits the window`).toBeLessThanOrEqual(940); + }); + + test('phone: stacks with no horizontal overflow @360x740', async ({ page }) => { + await page.setViewportSize({ width: 360, height: 740 }); + await page.goto(`${getBaseURL()}/signup`, { waitUntil: 'networkidle' }); + await page.waitForSelector('form', { timeout: 10_000 }); + const m = await page.evaluate(() => ({ + scrollW: document.documentElement.scrollWidth, + clientW: document.documentElement.clientWidth, + })); + expect(m.scrollW, `scrollW ${m.scrollW} should not exceed clientW ${m.clientW}`).toBeLessThanOrEqual(m.clientW + 1); + }); +});