diff --git a/api/derive.ts b/api/derive.ts index ecb5a4e..a257089 100644 --- a/api/derive.ts +++ b/api/derive.ts @@ -75,11 +75,27 @@ export const LADDER = [320, 480, 640, 960, 1280, 1920, 2560] as const; * Cropping in the browser is the right default when the shape is unknown. It is the wrong one when the * shape is known at build time, and for a carousel of square thumbnails it always is. * - * ── Only at thumbnail widths ── + * ── The rungs are chosen against real slots and real screens ── * - * These exist for grid slots. Anything larger is a picture being looked at, which is what the aspect - * ladder and the lightbox are for — and a square crop is a loss of information that only makes sense - * when the slot demands it. + * A gallery slot measures 193 CSS pixels on a phone and about 475 on a wide desktop, so the widths + * that matter are those times the pixel density somebody is actually holding: + * + * 193 x 1 = 193 -> 256 + * 193 x 1.75 = 338 -> 384 (Lighthouse's emulated phone, and most Android) + * 193 x 3 = 579 -> 640 (a dense phone) + * 475 x 1 = 475 -> 480 (desktop) + * 475 x 2 = 950 -> 960 (retina desktop) + * + * It was 320, 480, 640, and the middle of that is the problem: a phone needing 338 could not have it, + * so the browser correctly took 480 and downloaded 1.4x the pixels it could use. A rung is a few + * kilobytes of square WebP; a missing rung is paid for on every visit by everyone whose screen falls + * in the gap. + * + * 960 is here for the opposite reason — the ladder stopped at 640 and a retina desktop wanting 950 had + * nothing, so it took 640 and showed it soft. + * + * Above this, a picture is being looked at rather than browsed, which is what the aspect ladder and the + * lightbox are for. A square crop is lost information and only makes sense where the slot demands it. * * ── Centre, always ── * @@ -91,7 +107,7 @@ export const LADDER = [320, 480, 640, 960, 1280, 1920, 2560] as const; * It is a DEFAULT. A placement that sets its own crop keeps the aspect file and frames it in CSS — * see how the site chooses in src/media/render.ts. Nothing here knows about placements, and should not. */ -export const SQUARE_LADDER = [320, 480, 640] as const; +export const SQUARE_LADDER = [256, 384, 480, 640, 960] as const; /** * WebP quality, by rung.