From a3a500a3d28b1a0830dd40b580515b1a38ad9e5f Mon Sep 17 00:00:00 2001 From: Nibu Date: Mon, 9 Nov 2026 22:13:36 +0000 Subject: [PATCH 1/2] scene: skyState test measures ink against both sky ends and takes the worse Co-Authored-By: Claude Sonnet 5.5 --- src/app/features/scene/skyState.test.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/app/features/scene/skyState.test.ts b/src/app/features/scene/skyState.test.ts index 71d35fd0..65e0872d 100644 --- a/src/app/features/scene/skyState.test.ts +++ b/src/app/features/scene/skyState.test.ts @@ -131,22 +131,24 @@ describe('skyBackdrop', () => { }); }); -// Login text and link, per theme, from the card variables in pages/auth/styles.css.ts (the -// fallback pair serves Light, Silver, Dark and Butter) and the sky themes' baked bubble text and -// link. Light ink is measured against the lightest sky it can sit on, dark ink against the darkest. +// Login text and link, per theme, from the card variables in pages/auth/styles.css.ts and the sky +// themes' baked bubble text and link. The Light/Silver/Dark/Butter row uses the ink those themes +// actually render: under data-scene the auth card text is var(--sky-bubble-text, #b7c7d9), not each +// theme's own OnContainer. const inks = [ { theme: 'Light/Silver/Dark/Butter', text: '#b7c7d9', link: '#99c7ff' }, { theme: 'Midnight Sky', text: baked.midnight.bubbles.OtherText, link: baked.midnight.link }, { theme: 'Noonday Sky', text: baked.noonday.bubbles.OtherText, link: baked.noonday.link }, ]; -// WCAG contrast of an ink against a backdrop of the given luminance, with the ink's polarity -// deciding which end of the sky is its worst case. -const ratio = (ink: string, b: SkyBackdrop) => { +// WCAG contrast of an ink against the sky: the worse of its two ends, so a mid-luminance ink is +// measured against whichever end it is closer to. +const against = (ink: string, bg: number) => { const li = luminance(ink); - const bg = li > 0.18 ? b.lightest : b.darkest; const [hi, lo] = li > bg ? [li, bg] : [bg, li]; return (hi + 0.05) / (lo + 0.05); }; +const ratio = (ink: string, b: SkyBackdrop) => + Math.min(against(ink, b.lightest), against(ink, b.darkest)); describe('login ink against the sky backdrop', () => { const rows = SKY_STATES.flatMap((state) => -- 2.47.3 From 32cc8d6ad6226eee879b8c8c3ebfc3e9007e7c9b Mon Sep 17 00:00:00 2001 From: Nibu Date: Mon, 9 Nov 2026 22:16:39 +0000 Subject: [PATCH 2/2] scene: skyState test clamps the ink into the sky range for its worst case Co-Authored-By: Claude Sonnet 5.5 --- src/app/features/scene/skyState.test.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/app/features/scene/skyState.test.ts b/src/app/features/scene/skyState.test.ts index 65e0872d..4885abcd 100644 --- a/src/app/features/scene/skyState.test.ts +++ b/src/app/features/scene/skyState.test.ts @@ -140,15 +140,17 @@ const inks = [ { theme: 'Midnight Sky', text: baked.midnight.bubbles.OtherText, link: baked.midnight.link }, { theme: 'Noonday Sky', text: baked.noonday.bubbles.OtherText, link: baked.noonday.link }, ]; -// WCAG contrast of an ink against the sky: the worse of its two ends, so a mid-luminance ink is -// measured against whichever end it is closer to. +// WCAG contrast of an ink against the sky it is worst on. The sky can show any luminance between +// its darkest and lightest, and contrast is lowest where the backdrop is closest to the ink: the +// ink's own luminance clamped into that range. An ink inside the range can land on a backdrop of +// exactly its own luminance (1.00); an ink outside it is worst on the nearer end. const against = (ink: string, bg: number) => { const li = luminance(ink); const [hi, lo] = li > bg ? [li, bg] : [bg, li]; return (hi + 0.05) / (lo + 0.05); }; const ratio = (ink: string, b: SkyBackdrop) => - Math.min(against(ink, b.lightest), against(ink, b.darkest)); + against(ink, Math.min(b.lightest, Math.max(b.darkest, luminance(ink)))); describe('login ink against the sky backdrop', () => { const rows = SKY_STATES.flatMap((state) => -- 2.47.3