auth: a blurred, tinted, soft-edged band behind the sign-in footer (4.5:1 in Day, Dusk, Night) #61

Merged
void merged 4 commits from void/auth-footer-tint into dev 2026-11-10 03:45:34 +00:00
Member

Sign-in footer legibility (follow-ups chat-s5428-5428, chat-s5429-5429). Base dev 0931901b.

Problem, measured. WCAG contrast of the footer link ink against the pixels drawn behind it (sky/terrain frame with card and chrome hidden, 390x844@2x, real GPU: Chrome ANGLE D3D11 on a GTX 1070; the four links' boxes from the DOM; worst pixel over the four links):

state ink before: worst / mean after: worst / mean
Day #342d25 2.15 / 2.79 5.70 / 5.84
Dusk #342d25 1.00 / 1.12 5.02 / 5.12
Night #aeccff 3.80 / 6.48 11.15 / 11.38

Target 4.5:1 is met in all three states, on every pixel of every link box.

Treatment chosen (Meta's rule: no chrome, blur and tint, do not cover the sky). The footer line gets a backdrop-blur band (blur 12px) tinted with the plate's own fill (--sky-bubble, mixed at FOOTER_TINT = 0.82) and the plate's ink, with its edges faded out by a mask (16px top and bottom, 24px at the sides), so it reads as haze over the terrain and not as a card or pill. It applies only over the scene (:root[data-scene]). The sky is not touched: the band sits on the terrain at the foot of the page. Why not a text-shadow alone: the ink is the sky theme's dark ink, which on terrain of luminance 0.02-0.04 needs a light halo wide enough to be a glow, which reads worse than a soft tint; the tint also keeps the ink and link pairs the themes already verified (6.70 / 4.62 on the plate).

Review fixes (Libby), head 2e6d4d04. One footer rule (an earlier edit of mine had spliced into the sign-in card rule: a duplicate Y-only mask that overrode the side fade, a pill radius and a border); no radius or border; backgroundColor falls back to the plate's opaque fill where color-mix is missing, as the chat bubbles do (layout.css.ts); the test mixes in encoded sRGB like Chrome (fails at 0.80 with 4.36; 0.82 gives 4.55 over pure black, kept because the darkest terrain drawn is 0.0045, not black, and the drawn pixels clear 5.0). Side fade verified in a render (C-footer-dusk.png). Vitest src/app/features/scene + src/app/pages/auth: 23 files, 380 tests passed (on a node_modules copy plus @fontsource-variable/nunito, no npm ci). Preview: .../rat-sky-footer-tint-2e6d4d04/ (earlier ...-56bc40ab kept).

Tint value. 0.75 failed on the drawn pixels (Dusk 4.49 on two links): Chrome mixes in sRGB, the unit test blends in linear light, so the real contrast runs lower. 0.82 carries the margin (comment in skyPlate.ts). Hard fade at the sides was added after a first look showed a hard-edged bar.

Test. skyTheme.test.ts: for each state the plate's ink must clear AA over a band of FOOTER_TINT fill over a scene of luminance 0 and over the state's lightest backdrop. Setting FOOTER_TINT to 0.55 fails 2 tests. The test is a linear-light model; the real numbers above are the pixel measurement. Prettier and eslint clean; vitest src/app/features/scene and src/app/pages/auth: 380 passed.

Preview (new path, nothing overwritten): https://preview.gamecult.org/void/rat-sky-footer-tint-2e6d4d04/ (dev + this PR, terrain, tier low, demo). Intermediate builds at ...-ea238cf7 (tint 0.75) and ...-eb6efeee (0.82, no side fade) are kept. Measurements and shots: /opt/commons/handoff/ratatoskr-sky-shots/ (footer-contrast.json before, footer-contrast-after.json after, C-footer-*.png with text, C-band-*.png band only). Libby's blurband.mjs was not readable from this account (permission denied), so none of her numbers were reused.

Not merged; AuthFooter.tsx is unchanged, the footer is restyled by styles.css.ts.

🤖 Generated with Claude Code

Sign-in footer legibility (follow-ups chat-s5428-5428, chat-s5429-5429). Base dev 0931901b. **Problem, measured.** WCAG contrast of the footer link ink against the pixels drawn behind it (sky/terrain frame with card and chrome hidden, 390x844@2x, real GPU: Chrome ANGLE D3D11 on a GTX 1070; the four links' boxes from the DOM; worst pixel over the four links): | state | ink | before: worst / mean | after: worst / mean | |---|---|---|---| | Day | #342d25 | 2.15 / 2.79 | 5.70 / 5.84 | | Dusk | #342d25 | 1.00 / 1.12 | 5.02 / 5.12 | | Night | #aeccff | 3.80 / 6.48 | 11.15 / 11.38 | Target 4.5:1 is met in all three states, on every pixel of every link box. **Treatment chosen (Meta's rule: no chrome, blur and tint, do not cover the sky).** The footer line gets a backdrop-blur band (blur 12px) tinted with the plate's own fill (`--sky-bubble`, mixed at `FOOTER_TINT` = 0.82) and the plate's ink, with its edges faded out by a mask (16px top and bottom, 24px at the sides), so it reads as haze over the terrain and not as a card or pill. It applies only over the scene (`:root[data-scene]`). The sky is not touched: the band sits on the terrain at the foot of the page. Why not a text-shadow alone: the ink is the sky theme's dark ink, which on terrain of luminance 0.02-0.04 needs a light halo wide enough to be a glow, which reads worse than a soft tint; the tint also keeps the ink and link pairs the themes already verified (6.70 / 4.62 on the plate). **Review fixes (Libby), head 2e6d4d04.** One footer rule (an earlier edit of mine had spliced into the sign-in card rule: a duplicate Y-only mask that overrode the side fade, a pill radius and a border); no radius or border; `backgroundColor` falls back to the plate's opaque fill where color-mix is missing, as the chat bubbles do (layout.css.ts); the test mixes in encoded sRGB like Chrome (fails at 0.80 with 4.36; 0.82 gives 4.55 over pure black, kept because the darkest terrain drawn is 0.0045, not black, and the drawn pixels clear 5.0). Side fade verified in a render (C-footer-dusk.png). Vitest src/app/features/scene + src/app/pages/auth: 23 files, 380 tests passed (on a node_modules copy plus @fontsource-variable/nunito, no npm ci). Preview: .../rat-sky-footer-tint-2e6d4d04/ (earlier ...-56bc40ab kept). **Tint value.** 0.75 failed on the drawn pixels (Dusk 4.49 on two links): Chrome mixes in sRGB, the unit test blends in linear light, so the real contrast runs lower. 0.82 carries the margin (comment in skyPlate.ts). Hard fade at the sides was added after a first look showed a hard-edged bar. **Test.** `skyTheme.test.ts`: for each state the plate's ink must clear AA over a band of `FOOTER_TINT` fill over a scene of luminance 0 and over the state's lightest backdrop. Setting `FOOTER_TINT` to 0.55 fails 2 tests. The test is a linear-light model; the real numbers above are the pixel measurement. Prettier and eslint clean; vitest src/app/features/scene and src/app/pages/auth: 380 passed. **Preview (new path, nothing overwritten):** https://preview.gamecult.org/void/rat-sky-footer-tint-2e6d4d04/ (dev + this PR, terrain, tier low, demo). Intermediate builds at ...-ea238cf7 (tint 0.75) and ...-eb6efeee (0.82, no side fade) are kept. Measurements and shots: /opt/commons/handoff/ratatoskr-sky-shots/ (`footer-contrast.json` before, `footer-contrast-after.json` after, `C-footer-*.png` with text, `C-band-*.png` band only). Libby's blurband.mjs was not readable from this account (permission denied), so none of her numbers were reused. Not merged; `AuthFooter.tsx` is unchanged, the footer is restyled by `styles.css.ts`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The footer links sat on dark terrain in the sky's dark ink (contrast 1.0 to 2.9 at Dusk and
Day). The footer now carries the plate's ink over a backdrop-blur band tinted with the plate's
fill (FOOTER_TINT), faded at its edges; skyTheme.test.ts checks the ink over the darkest and
lightest scene behind it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
auth: fade the footer band at its sides too
Some checks failed
Build pull request / Build pull request (pull_request) Has been cancelled
56bc40abe6
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
auth: footer band review fixes: one block, no pill or border, color-mix fallback, sRGB test
All checks were successful
Build pull request / Build pull request (pull_request) Successful in 2m45s
2e6d4d042a
The first footer block had spliced into the sign-in card's rule (a Y-only mask duplicate that
overrode the side fade, a pill radius and border on the footer); the footer is now one rule.
The test mixes in encoded sRGB as Chrome does.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
void merged commit 30ae5154f5 into dev 2026-11-10 03:45:34 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/Ratatoskr!61
No description provided.