From d491437e324a6f253f2712fbd1d7a4aeeee2b894 Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Tue, 18 Aug 2026 22:34:37 +0200 Subject: [PATCH] feat: let the reader zoom in two steps closer than a week MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Events routinely end within a day of each other, and at the old close end of the ladder their bar ends were a few pixels apart — the board being asked the one question it exists to answer and telling the reader to squint. Seventy-two and 108 px/day separate them, and give a one-day event a bar wide enough to read and to tap rather than the 34px every short bar collapses to. The clamp test now reads the ladder's last rung instead of naming 48, so extending it again does not need the test rewritten. Co-Authored-By: Claude Opus 5 (1M context) --- src/client/state/zoom.ts | 13 +++++++++++-- test/zoom.test.ts | 14 +++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/client/state/zoom.ts b/src/client/state/zoom.ts index a810a59..b2d2947 100644 --- a/src/client/state/zoom.ts +++ b/src/client/state/zoom.ts @@ -9,8 +9,17 @@ * `prefs` stores the chosen value and the two must agree on what is valid. */ -/** The ladder, in px per day. Roughly a third wider at each step. */ -export const DAY_WIDTHS = [6, 9, 13, 20, 32, 48] as const; +/** + * The ladder, in px per day. Roughly half again wider at each step. + * + * It runs from a quarter of calendar on one screen to a single day being wider + * than a finger. The close end is not decoration: several events routinely end + * within a day of each other, and at 48px a day their bar ends are a few pixels + * apart — which is the moment a reader is asking the board the one question it + * exists to answer, and being told to squint. Going in further separates them, + * and gives a one-day event a bar wide enough to read and to tap. + */ +export const DAY_WIDTHS = [6, 9, 13, 20, 32, 48, 72, 108] as const; /** * The scale the board opens at for a reader who has never touched the control. diff --git a/test/zoom.test.ts b/test/zoom.test.ts index a21060a..df09a0f 100644 --- a/test/zoom.test.ts +++ b/test/zoom.test.ts @@ -27,7 +27,7 @@ describe("snapDayWidth", () => { // close to what its reader chose. expect(snapDayWidth(10)).toBe(9); expect(snapDayWidth(7)).toBe(6); - expect(snapDayWidth(1000)).toBe(48); + expect(snapDayWidth(1000)).toBe(DAY_WIDTHS[DAY_WIDTHS.length - 1]!); // Exactly between two steps takes the wider one: ties go to the more // legible board. expect(snapDayWidth(11)).toBe(13); @@ -56,6 +56,18 @@ describe("stepDayWidth", () => { expect(stepDayWidth(narrowest, -1)).toBe(narrowest); }); + test("the close end goes past a week on screen", () => { + // Several events routinely end within a day of each other, and the reader + // has to be able to tell those ends apart — at 48px a day they are a few + // pixels between. + expect(canStep(48, 1)).toBe(true); + expect(stepDayWidth(48, 1)).toBe(72); + const widest = DAY_WIDTHS[DAY_WIDTHS.length - 1]!; + // A single day wider than a fingertip, so a one-day event is readable and + // tappable rather than the 34px minimum bar. + expect(widest).toBeGreaterThanOrEqual(96); + }); + test("canStep says when a control has nowhere left to go", () => { expect(canStep(DAY_WIDTHS[0]!, -1)).toBe(false); expect(canStep(DAY_WIDTHS[0]!, 1)).toBe(true);