Cross-Browser Compatibility Audit¶
App: Circuit Breaker (Vite/React SPA) Audit type: Code-level static analysis + CSS/JS feature review Date: 2026-02-28 Auditor: Claude Code
Scope¶
| Area | Covered |
|---|---|
| CSS feature support | ✓ |
| JS/ES feature support | ✓ |
| Input/form behavior | ✓ (autofill fix applied) |
| Graph map interactions | ✓ |
| Responsive / small screen | ✓ (existing media queries reviewed) |
| Build/bundling config | ✓ |
| Live browser testing | ✗ (out of scope — requires hardware) |
1. Issue List¶
Issue A — color-mix() without fallbacks¶
| Attribute | Value |
|---|---|
| Severity | Major |
| Category | CSS |
| Browsers affected | Chrome < 111, Firefox < 113, Safari < 16.2, Edge < 111 |
| Symptom | Dock pills, command palette, table row hovers, and login page decorations lose all background, border, and glow styling — elements appear as transparent outlines or become invisible |
| Root cause | color-mix(in srgb, ...) used in 28 declarations across main.css with no fallback value. Browsers that do not support this function silently discard the entire declaration. |
| Files | frontend/src/styles/main.css — lines 151–207 (dock), 269–347 (palette), 520 (table), 1076–1109 (login), 1364–1392 (mobile) |
| Status | ✅ Fixed — each color-mix() declaration is now preceded by an equivalent rgba() fallback using the cyberpunk-neon default palette. CSS cascade ensures the fallback is used when color-mix() is not understood. |
Issue B — Input autofill clashes with dark theme¶
| Attribute | Value |
|---|---|
| Severity | Major |
| Category | CSS / UX |
| Browsers affected | Chrome, Edge (yellow background), Safari (light-blue background) |
| Symptom | When the browser autofills the email/password on the login form, it overrides the input background with its own autofill colour, creating a jarring yellow or light-blue flash on the dark-themed login card. |
| Root cause | The existing -webkit-autofill override only targets .form-group input. The login form uses .login-input (a separate component style), which had no autofill override. |
| Files | frontend/src/styles/main.css — missing rule for .login-input:-webkit-autofill |
| Status | ✅ Fixed — added -webkit-autofill block for .login-input after .login-input:focus, matching the existing pattern used for .form-group input. Uses --color-bg inset box-shadow trick to suppress the browser colour and --color-text for text fill. |
Issue C — No explicit Vite build target¶
| Attribute | Value |
|---|---|
| Severity | Minor |
| Category | Build |
| Browsers affected | All (build configuration concern) |
| Symptom | Vite defaulted to esnext transpilation target with no explicit minimum browser floor. Modern syntax accidentally introduced above the target level would silently ship without transpilation. |
| Root cause | vite.config.js had no build.target field. |
| Files | frontend/vite.config.js |
| Status | ✅ Fixed — added build.target: ['chrome111', 'firefox113', 'safari16.4', 'edge111']. These are the first versions that support color-mix(), the most advanced CSS feature used. The target documents the minimum browser floor and ensures Vite can warn if future JS syntax falls below this baseline. |
Issue D — backdrop-filter graceful degradation (informational)¶
| Attribute | Value |
|---|---|
| Severity | Info (no action required) |
| Category | CSS |
| Browsers affected | Firefox < 103 (no backdrop-filter support) |
| Symptom | Dock pills and command palette lose glass blur effect. Elements remain fully functional with their solid background colour. |
| Root cause | backdrop-filter: blur() requires Firefox 103+. |
| Existing mitigations | -webkit-backdrop-filter prefix already present (covers Safari). The background property is set independently so Firefox < 103 falls through to a visible solid background. This is acceptable degradation — no code change needed. |
| Status | No change — degradation is graceful and acceptable. |
Issue E — ReactFlow preventScrolling not pinned¶
| Attribute | Value |
|---|---|
| Severity | Minor |
| Category | JS / UX |
| Browsers affected | All (future-proofing concern) |
| Symptom | When hovering the topology map and scrolling, ReactFlow's default preventScrolling=true captures wheel events correctly — but this behaviour was not explicitly declared in the JSX, meaning a ReactFlow version bump that changes the default would silently break scroll isolation. |
| Root cause | Prop not set in <ReactFlow> component; relied on library default. |
| Files | frontend/src/pages/MapPage.jsx — <ReactFlow> component |
| Status | ✅ Fixed — preventScrolling prop explicitly added. |
Issue F — color-mix() inside filter: drop-shadow() (compound)¶
| Attribute | Value |
|---|---|
| Severity | Major |
| Category | CSS |
| Browsers affected | Chrome < 111, Firefox < 113, Safari < 16.2 |
| Symptom | On the dock, the entire filter declaration is dropped when color-mix() inside drop-shadow() is unsupported. This removes the glow effect AND any transform/transition applied via filter. |
| Root cause | If any function in a filter value is invalid, the browser discards the whole filter declaration (not just the unsupported part). Two instances: .dock-item:hover svg and .dock-item.active svg. |
| Files | frontend/src/styles/main.css lines 178, 192 |
| Status | ✅ Fixed — fallback filter: drop-shadow(... rgba(...)) added before each declaration. |
2. Compatibility Checklist¶
Minimum supported versions: Chrome 111, Firefox 113, Safari 16.4, Edge 111.
| Flow | Chrome 111+ | Firefox 113+ | Safari 16.4+ | Edge 111+ |
|---|---|---|---|---|
| Login (form, autofill, submit) | ✓ | ✓ | ✓ | ✓ |
| Topology map (pan/zoom/drag) | ✓ | ✓ | ✓ | ✓ |
| Context menu (right-click nodes) | ✓ | ✓ | ✓ | ✓ |
| Hardware / Services CRUD | ✓ | ✓ | ✓ | ✓ |
| Settings — Appearance / Themes | ✓ | ✓ | ✓ | ✓ |
| Settings — Branding | ✓ | ✓ | ✓ | ✓ |
| Docs editor (Markdown) | ✓ | ✓ † | ✓ | ✓ |
| Dock (navigation, scroll, reorder) | ✓ | ✓ | ✓ | ✓ |
| Light / dark / auto theme modes | ✓ | ✓ | ✓ | ✓ |
| Responsive at 768px (mobile) | ✓ | ✓ | ✓ | ✓ |
† Firefox Docs editor note: @uiw/react-md-editor uses Ctrl+K as the "Insert Link" shortcut. In Firefox, Ctrl+K may focus the browser's address bar when no editable element has focus. When the editor is focused, the shortcut is captured by the page first — this is expected browser behaviour and the shortcut should work correctly. No code change required; low risk.
One version behind (Chrome 110 / Firefox 112 / Safari 16.1)¶
With the fallbacks applied in this audit, the app degrades gracefully to the cyberpunk-neon colour palette's rgba() equivalents:
- All dock / palette glass surfaces use rgba backgrounds instead of color-mix() transparency.
- Drop-shadow glows use fixed rgba(0, 212, 255, α) instead of theme-adaptive values.
- Overall visual appearance is correct for the default dark theme; light theme and non-default presets will display the cyberpunk-neon colours rather than the active theme's colours for these specific surfaces.
3. JS/ES Feature Review¶
All features checked against the minimum target (Chrome 111 / Firefox 113 / Safari 16.4):
| Feature | Usage in codebase | Browser support |
|---|---|---|
Optional chaining ?. |
Heavy (MapPage, detail panels) | Chrome 80+, FF 74+, Safari 13.1+ ✓ |
Nullish coalescing ?? |
Heavy (fallback values throughout) | Chrome 80+, FF 72+, Safari 13.1+ ✓ |
Object.fromEntries() |
Multiple pages (ID→name maps) | Chrome 73+, FF 63+, Safari 12.1+ ✓ |
Object.entries() |
MapPage, config files | Chrome 54+, FF 47+, Safari 10.1+ ✓ |
Array.from() |
DocEditor (drag-drop files) | Chrome 45+, FF 32+, Safari 9+ ✓ |
import.meta.env |
AuthContext (Vite env vars) | Vite compile-time replacement ✓ |
window.matchMedia() |
SettingsContext (auto dark mode) | Chrome 9+, FF 6+, Safari 5.1+ ✓ |
CSS color-mix() |
main.css (28 uses) | Chrome 111+, FF 113+, Safari 16.2+ — fallbacks added ✓ |
CSS backdrop-filter |
main.css (3 uses) | Chrome 76+, FF 103+, Safari 9+ (with -webkit-) ✓ |
CSS gap on flex |
main.css (10+ uses) | Chrome 84+, FF 63+, Safari 14.1+ ✓ |
CSS mask-image |
main.css (dock fade) | Chrome 120+, FF 53+, Safari 15.4+ (with -webkit-) ✓ |
No flatMap, structuredClone, or dynamic import() usage found — no concerns.
4. Follow-Up Tasks¶
FU-1 — Playwright automated cross-browser regression suite¶
Priority: High Description: Set up a Playwright test suite targeting Chromium, Firefox, and WebKit (Safari). Key flows to automate: - Login with autofill simulation - Topology map pan/zoom gesture - Context menu open/close - Settings theme switching - Docs editor keyboard shortcuts
bash
npm install -D @playwright/test
npx playwright install chromium firefox webkit
Write tests in frontend/tests/ with playwright.config.ts targeting baseURL: http://localhost:5173.
FU-2 — Monitor color-mix() coverage as themes expand¶
Priority: Medium
Description: The 28 color-mix() fallbacks added in this audit use hardcoded rgba() values from the cyberpunk-neon default palette. If new components or theme features are added that introduce additional color-mix() calls, those also need fallbacks. Consider a lint rule or CI check:
```bash
CI check: count color-mix usages vs documented fallback count¶
grep -c "color-mix" frontend/src/styles/main.css ```
Alternatively, adopt @supports (color: color-mix(in srgb, red, blue)) blocks for new additions instead of the cascade-fallback pattern — cleaner for future authors.
FU-3 — Safari 16.0 / 16.1 advisory (macOS Monterey)¶
Priority: Low
Description: Safari 16.0 and 16.1 (shipped with macOS 12 Monterey) do not support color-mix(). Users on these versions will see the rgba fallbacks rather than the active theme's adaptive colours. Consider adding a browser upgrade advisory for these versions:
javascript
// Detect in SettingsContext.jsx
const supportsColorMix = CSS.supports('color', 'color-mix(in srgb, red, blue)');
if (!supportsColorMix) {
// show subtle toast: "For the best experience, update Safari to 16.4+"
}
FU-4 — Confirm iPadOS Safari / Android Chrome smoke¶
Priority: Low
Description: The app has responsive CSS at max-width: 768px (single-column login, stacked settings, bottom nav dock). A quick manual smoke test on an iPad or emulator is recommended before ship:
- Login card renders without overflow
- Map is navigable with touch/pinch
- Settings sections scroll correctly