From 9f8bf98a946fce2a61d2a5bb489cca3e6ca33dc3 Mon Sep 17 00:00:00 2001 From: alexpolo Date: Sun, 9 Aug 2026 13:44:23 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20two=20real=20bugs=20found=20via=20live?= =?UTF-8?q?=20Playwright=20QA=20=E2=80=94=20decoration=20z-index=20and=20c?= =?UTF-8?q?olor=20accuracy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Did a real browser QA pass against the deployed site (Playwright, not just isolated HTML harnesses) and found two actual bugs the harness-based checks couldn't catch: - FloatingBg/Sparkles are `position: fixed` full-viewport layers with z-index: 1, while page content like .pony-card only has z-index: auto. Per CSS stacking rules a positioned z-index:1 sibling paints above z-index:auto content regardless of DOM order, so the floating ponies were rendering on top of / poking through the theme-select cards. Changed both to z-index: -1 so they reliably sit behind all normal content. - COLOR_OPTIONS' hue-rotate values were tuned against the wrong baseline hue: base.png's actual body hue is ~0deg (red), but e.g. "Blå" (blue) used hue-rotate(150deg), landing on ~150deg = green, and "Lilla" (purple) used 220deg, landing on ~220deg = blue. Recalibrated all rotations against the real measured base hue so picking a color now actually produces that color on the body. Verified before/after with a side-by-side render of all 8 colors, then confirmed live against the deployed site (clicking "Kropsfarve: Blå" now visibly turns the body blue, not green). 67/67 tests still passing. Co-Authored-By: Claude Sonnet 5 --- pony-frontend/src/App.css | 4 ++-- pony-frontend/src/pixelPony/spriteData.js | 19 +++++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/pony-frontend/src/App.css b/pony-frontend/src/App.css index ff26a3b..7fc0fe6 100644 --- a/pony-frontend/src/App.css +++ b/pony-frontend/src/App.css @@ -1436,7 +1436,7 @@ body { position: fixed; inset: 0; pointer-events: none; - z-index: 1; + z-index: -1; } .sparkle { @@ -1449,7 +1449,7 @@ body { position: fixed; inset: 0; pointer-events: none; - z-index: 1; + z-index: -1; } .floating-pony { diff --git a/pony-frontend/src/pixelPony/spriteData.js b/pony-frontend/src/pixelPony/spriteData.js index db91e80..77958e2 100644 --- a/pony-frontend/src/pixelPony/spriteData.js +++ b/pony-frontend/src/pixelPony/spriteData.js @@ -59,14 +59,21 @@ export const WING_STYLES = [ { id: 'spread', label: 'Udspredt', file: '/sprites/pony/wing-spread.png' }, ]; +// hue-rotate degrees are calibrated against base.png's own hue (~0deg, red) +// so the *body* color actually matches its label (previously "Blå" rendered +// green and "Lilla" rendered blue, since the rotations were tuned for a +// baseline that didn't match the real sprite). Mane/tail/horn sit at a +// different baseline hue (~30deg, orange), so the same rotation lands on a +// nearby-but-not-identical hue there -- an accepted tradeoff of sharing one +// palette across every layer. export const COLOR_OPTIONS = [ { id: 'original', label: 'Original', filter: 'none' }, - { id: 'pink', label: 'Lyserød', filter: 'hue-rotate(300deg) saturate(1.3)' }, - { id: 'purple', label: 'Lilla', filter: 'hue-rotate(220deg) saturate(1.4)' }, - { id: 'blue', label: 'Blå', filter: 'hue-rotate(150deg) saturate(1.5)' }, - { id: 'teal', label: 'Turkis', filter: 'hue-rotate(120deg) saturate(1.4)' }, - { id: 'green', label: 'Grøn', filter: 'hue-rotate(80deg) saturate(1.3)' }, - { id: 'yellow', label: 'Gul', filter: 'hue-rotate(-30deg) saturate(1.5) brightness(1.15)' }, + { id: 'pink', label: 'Lyserød', filter: 'hue-rotate(330deg) saturate(1.3)' }, + { id: 'purple', label: 'Lilla', filter: 'hue-rotate(275deg) saturate(1.4)' }, + { id: 'blue', label: 'Blå', filter: 'hue-rotate(215deg) saturate(1.5)' }, + { id: 'teal', label: 'Turkis', filter: 'hue-rotate(180deg) saturate(1.4)' }, + { id: 'green', label: 'Grøn', filter: 'hue-rotate(125deg) saturate(1.3)' }, + { id: 'yellow', label: 'Gul', filter: 'hue-rotate(50deg) saturate(1.5) brightness(1.15)' }, { id: 'white', label: 'Hvid', filter: 'saturate(0.15) brightness(1.7)' }, { id: 'black', label: 'Sort', filter: 'brightness(0.35)' }, ];