diff --git a/frontend/src/AppDevelopmentPreview.contract.test.ts b/frontend/src/AppDevelopmentPreview.contract.test.ts index 26e599a..17e233a 100644 --- a/frontend/src/AppDevelopmentPreview.contract.test.ts +++ b/frontend/src/AppDevelopmentPreview.contract.test.ts @@ -85,6 +85,18 @@ describe('browser development preview contract', () => { ) }) + it('replaces rectangular CEF focus outlines on the side hardware controls', () => { + expect(mainCss).toMatch( + /\.phone-hardware-button:focus\s*\{[^}]*outline:\s*none;/s, + ) + expect(mainCss).toMatch( + /\.phone-hardware-button:focus-visible::after\s*\{[^}]*width:\s*3px;[^}]*height:\s*24px;[^}]*border-radius:\s*999px;[^}]*background:\s*#0a84ff;/s, + ) + expect(mainCss).not.toMatch( + /\.phone-hardware-button:focus-visible\s*\{[^}]*outline:/s, + ) + }) + it('consumes Escape synchronously before FiveM can open the pause menu', () => { expect(source).toContain("import { consumeEscape } from '@/utils/keyboard'") expect(source).toContain( diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css index 69214a3..a9dbbbb 100644 --- a/frontend/src/assets/main.css +++ b/frontend/src/assets/main.css @@ -380,9 +380,27 @@ button { .phone-hardware-button:disabled { cursor: default; } -.phone-hardware-button:focus-visible { - outline: 2px solid #fff; - outline-offset: -6px; +.phone-hardware-button:focus { + outline: none; +} +.phone-hardware-button:focus-visible::after { + position: absolute; + top: 50%; + width: 3px; + height: 24px; + border-radius: 999px; + background: #0a84ff; + box-shadow: 0 0 0 1px rgb(255 255 255 / 90%); + content: ''; + transform: translateY(-50%); +} +.phone-hardware-button--action:focus-visible::after, +.phone-hardware-button--volume-up:focus-visible::after, +.phone-hardware-button--volume-down:focus-visible::after { + right: 7px; +} +.phone-hardware-button--power:focus-visible::after { + left: 7px; } .phone-hardware-button--action { top: 176px;