Skip to content

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