Gate 7 — Responsive Audit (Ticket #3273, Forgot-Password Flow) ================================================================ Date: 2026-09-08 Feature files: app/(auth)/forgot-password/page.tsx app/(auth)/forgot-password/verify/page.tsx app/(auth)/forgot-password/reset/page.tsx components/auth/ForgotPasswordForm.tsx components/auth/VerifyOtpForm.tsx components/auth/ResetPasswordForm.tsx components/auth/SignInForm.tsx Shared deps examined: components/auth/BrandPanel.tsx components/ui/SubmitButton.tsx components/ui/fields/PasswordField.tsx components/ui/button.tsx app/(auth)/layout.tsx app/(auth)/login/page.tsx app/globals.css tailwind.config.ts screen_inventory: Skill resolution: [components] read_file(".claude/skills/nextjs-tailwind-responsive-components-audit/SKILL.md") [desktop] read_file(".claude/skills/nextjs-tailwind-responsive-desktop-audit/SKILL.md") [mobile] read_file(".claude/skills/nextjs-tailwind-responsive-mobile-audit/SKILL.md") [tablet] read_file(".claude/skills/nextjs-tailwind-responsive-tablet-breakpoint-audit/SKILL.md") [typography] read_file(".claude/skills/nextjs-tailwind-responsive-typography-audit/SKILL.md") [ux-consistency] read_file(".claude/skills/nextjs-tailwind-responsive-ux-consistency-audit/SKILL.md") Tailwind breakpoints (default, no overrides in tailwind.config.ts): sm=640px md=768px lg=1024px xl=1280px 2xl=1536px Key observation: ZERO responsive breakpoint prefixes (sm:/md:/lg:/xl:) found in any of the seven feature files or BrandPanel. The entire auth flow has no responsive adaptations. ================================================================================ MERGED FINDINGS ================================================================================ --- FINDING 1 (P1) --- Tags: [mobile] [components] [tablet] File: components/auth/BrandPanel.tsx (line 7) Component: BrandPanel Problem: BrandPanel uses `w-[45%] shrink-0` with no responsive hiding or collapsing. It occupies 45% of viewport at ALL widths — including mobile. At 320px → 144px for BrandPanel, 176px remaining for the form. At 375px → ~169px for BrandPanel, ~206px remaining for the form. At 640px (sm) → 288px for BrandPanel, 352px remaining. The form containers need 360-480px, so they overflow or are crushed. Evidence: className="relative h-full w-[45%] shrink-0 overflow-hidden bg-accent" No sm:/md:/lg: prefixes. No hidden/md:block pattern. Why it matters: The auth flow is completely unusable on any device below ~800px. Forms overflow their container or are clipped. This is a blocking mobile/tablet issue affecting all four auth screens (login, forgot-password, verify, reset). Recommended fix: Add `hidden lg:block` to BrandPanel wrapper (hide below 1024px), or `hidden md:block` (hide below 768px). The form-side container should become the full-width layout on mobile. Pattern: `` and ensure the right-side form container doesn't depend on BrandPanel being present. Risk of change: Low — BrandPanel is purely decorative/branding, hides no actionable content. The three-file shell (login/page.tsx, ForgotPasswordForm, VerifyOtpForm, ResetPasswordForm) needs the same change. Fixed: false --- FINDING 2 (P1) --- Tags: [mobile] [tablet] File: components/auth/ForgotPasswordForm.tsx (line 27) Component: ForgotPasswordForm — form container Problem: Form uses `w-[360px]` — a fixed pixel width with no responsive fallback. On mobile (even if BrandPanel were hidden), 360px exceeds 320px viewport, and on a 375px viewport the form would touch both edges with no padding. Evidence: className="flex w-[360px] flex-col gap-1.5" Compare with SignInForm (line 18): className="flex w-full max-w-[360px] flex-col gap-1.5" SignInForm uses `w-full max-w-[360px]` which is the correct mobile-safe pattern. Why it matters: Horizontal overflow on mobile — the form extends past the viewport edge, parts of the input and button are unreachable. Recommended fix: Change `w-[360px]` to `w-full max-w-[360px] px-6` (same pattern as ResetPasswordForm, or `w-full max-w-[360px]` like SignInForm). Risk of change: None — at desktop widths max-w-[360px] renders identically to w-[360px]. Fixed: false --- FINDING 3 (P1) --- Tags: [mobile] [tablet] File: components/auth/VerifyOtpForm.tsx (line 103) Component: VerifyOtpForm — form container Problem: Same fixed-width issue as Finding 2. Form uses `w-[360px]` instead of `w-full max-w-[360px]`. Evidence: className="flex w-[360px] flex-col gap-1.5" Why it matters: Same overflow as Finding 2. Additionally, the OTP digit boxes inside need 338px minimum (see Finding 4), so even a `max-w-[360px]` container barely fits them. Recommended fix: Change to `w-full max-w-[360px] px-4` or `w-full max-w-[400px] px-6`. Risk of change: None at desktop. Fixed: false --- FINDING 4 (P1) --- Tags: [mobile] File: components/auth/VerifyOtpForm.tsx (lines 123-146) Component: VerifyOtpForm — OTP digit boxes Problem: 6 digit inputs × w-12 (48px) + 5 × gap-[10px] (50px) = 338px minimum width. Even if BrandPanel is hidden and the form is full-width, 338px overflows a 320px viewport. At 360-375px with any padding, the boxes are crushed or overflow. Evidence: className="flex gap-[10px] mb-2" (container) Each input: className="h-[52px] w-12 rounded-md ..." 6 × 48 + 5 × 10 = 338px hard minimum. Why it matters: OTP entry — the core action of this screen — is physically impossible on a small mobile device. Boxes overflow and the rightmost digits are unreachable. Recommended fix: At mobile widths, reduce box size to w-10 (40px) and gap to gap-1.5 (6px): 6×40+5×6 = 270px, fits comfortably in 320px with padding. Pattern: `className="flex gap-1.5 sm:gap-[10px] mb-2"` and per-box `className="h-11 w-10 sm:h-[52px] sm:w-12 ..."`. Risk of change: Low — smaller boxes are still easily tappable at 40×44px. Fixed: false --- FINDING 5 (P2) --- Tags: [mobile] [components] File: components/ui/fields/PasswordField.tsx (lines 66-72) Component: PasswordField — show/hide toggle button Problem: Toggle button has no explicit touch-target sizing. The rendered tappable area is approximately 16×16px (the Eye/EyeOff icon is `h-4 w-4`). No padding on the