diff --git a/public/live.css b/public/live.css index 6e033e5b..f347dc02 100644 --- a/public/live.css +++ b/public/live.css @@ -1104,12 +1104,20 @@ input.live-node-filter-input:focus { padding: 4px 10px; border-radius: 4px; cursor: pointer; - transition: all 0.15s; + /* #1528: transition was `all 0.15s` which animated background-color + + * border-color when --accent-bg / --accent-border changed at runtime + * (e.g. customizer overrides, or the Playwright sentinel-swap in + * test-e2e-playwright.js #1528). getComputedStyle() polled immediately + * after the var swap returned the mid-flight (≈old) value, breaking + * the theming-illusion guard test. Restrict the transition to props + * that are NOT bound to themable tokens so token swaps render + * instantly. */ + transition: color 0.15s, transform 0.15s; } .vcr-scope-btn.active { - background: rgba(59,130,246,0.2); + background: var(--accent-bg, rgba(59,130,246,0.2)); color: var(--text); - border-color: rgba(59,130,246,0.3); + border-color: var(--accent-border, rgba(59,130,246,0.3)); } .vcr-timeline-container { diff --git a/public/style.css b/public/style.css index 71ccff6e..a17793c5 100644 --- a/public/style.css +++ b/public/style.css @@ -2674,7 +2674,7 @@ button.ch-item.ch-item-encrypted .ch-badge { filter: grayscale(0.6); } cursor: pointer; transition: background 0.15s; } -.copy-link-btn:hover { background: rgba(59, 130, 246, 0.25); } +.copy-link-btn:hover { background: var(--accent-border, rgba(59, 130, 246, 0.25)); } /* Route tooltip on map */ .route-tooltip { diff --git a/test-e2e-playwright.js b/test-e2e-playwright.js index b060a5a6..f1ef4d0b 100644 --- a/test-e2e-playwright.js +++ b/test-e2e-playwright.js @@ -3392,6 +3392,30 @@ async function run() { } }); + await test('#1528 .vcr-scope-btn.active background tracks --accent-bg (token swap, not blue literal)', async () => { + await page.goto(`${BASE}/#/live`, { waitUntil: 'domcontentloaded' }); + await page.waitForSelector('.vcr-scope-btn.active', { timeout: 8000 }); + const result = await page.evaluate(() => { + const el = document.querySelector('.vcr-scope-btn.active'); + // Override --accent-bg with a clearly non-blue sentinel so we can detect + // whether the rule actually consumes the token (good) or a hardcoded + // rgba(59,130,246,...) literal (bad — the theming illusion this fix targets). + // Use !important so we beat any customizer-injected :root override. + document.documentElement.style.setProperty('--accent-bg', 'rgb(255, 0, 0)', 'important'); + document.documentElement.style.setProperty('--accent-border', 'rgb(0, 200, 0)', 'important'); + const bg = window.getComputedStyle(el).backgroundColor; + const border = window.getComputedStyle(el).borderColor; + document.documentElement.style.removeProperty('--accent-bg'); + document.documentElement.style.removeProperty('--accent-border'); + return { bg, border }; + }); + // Background should reflect our sentinel red, not blue. + assert(/^rgb\(255,\s*0,\s*0\)/.test(result.bg), + `.vcr-scope-btn.active bg should track --accent-bg, got ${result.bg}`); + assert(/^rgb\(0,\s*200,\s*0\)/.test(result.border), + `.vcr-scope-btn.active border should track --accent-border, got ${result.border}`); + }); + await browser.close(); // Summary