From 080306f111ff5425b649b624414887000b604205 Mon Sep 17 00:00:00 2001 From: Martin Dvorak Date: Wed, 7 Oct 2026 12:14:10 +0000 Subject: [PATCH] Stop phones zooming when a field is focused - Viewport: maximum-scale=1 and user-scalable=no (app-like, no pinch or double-tap zoom on phones). - Mobile-only rule keeps every input/textarea/select at 16px so iOS Safari's focus auto-zoom never triggers (it ignores user-scalable=no for that). Deliberately unlayered so it beats the per-component Tailwind sizes; desktop keeps the designed 12-14px fields. New zoom suite (6 checks): viewport meta, gate input, settings key input, notes textarea and every study-feed field at >= 16px on a phone, desktop sizes unchanged. Install sheet 64/64, pwa 16/16, final-ux 12/12, security 8/8, contrast 20/20. --- README.md | 4 ++++ app/globals.css | 12 ++++++++++++ app/layout.tsx | 6 +++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d28fde..46c37f1 100644 --- a/README.md +++ b/README.md @@ -777,6 +777,10 @@ Things I chose while building, with the reasoning: device, uses Chrome's deferred `beforeinstallprompt` for a one-tap install where available, and stays reachable from Settings. It is mounted in the root layout, so it can appear over any screen — including the key gate — without blocking the page underneath. +30. **Phones don't zoom, and mobile fields are 16px.** The viewport sets `maximum-scale=1` / + `user-scalable=no` for an app-like feel, and a mobile-only rule keeps every input and textarea at + 16px so iOS Safari's focus auto-zoom never fires (iOS ignores `user-scalable=no` for that). + Desktop keeps the designed 12–14px field sizes. 14. **`gpt-oss:120b` does all content work — but it cannot read images** (`this model does not support image input`), so `VISION_MODEL` has to stay a multimodal model (`gemma4:31b-cloud`). Text-only inputs — pasted text, PDFs with a text layer, DOCX/PPTX/ODT — never touch the vision diff --git a/app/globals.css b/app/globals.css index 7315bcb..97dd60b 100644 --- a/app/globals.css +++ b/app/globals.css @@ -550,6 +550,18 @@ body { } } +/* Mobile form fields ----------------------------------------------------- */ +/* iOS Safari zooms the whole page when a focused field's text is under 16px + (it ignores user-scalable=no for that). Deliberately unlayered so it wins + over the per-component Tailwind sizes, and only on phone-sized screens. */ +@media (max-width: 639px) { + input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), + textarea, + select { + font-size: 16px; + } +} + /* Reduced motion --------------------------------------------------------- */ @media (prefers-reduced-motion: reduce) { *, diff --git a/app/layout.tsx b/app/layout.tsx index 970bb6c..7705146 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -41,7 +41,11 @@ export const metadata: Metadata = { export const viewport: Viewport = { width: "device-width", initialScale: 1, - maximumScale: 5, + // Phones: no pinch/double-tap zoom (the app-like feel). The input font-size + // rule in globals.css is what actually stops iOS Safari's focus auto-zoom, + // which ignores user-scalable=no. + maximumScale: 1, + userScalable: false, viewportFit: "cover", themeColor: [ { media: "(prefers-color-scheme: light)", color: "#f8fafc" },