febd617c56
CI / Lint (ruff) (pull_request) Successful in 8s
CI / Tests (py3.10 / ubuntu-latest) (pull_request) Successful in 12s
CI / Tests (py3.12 / ubuntu-latest) (pull_request) Successful in 10s
CI / Tests (py3.13 / ubuntu-latest) (pull_request) Successful in 11s
CI / Catalog signature (pull_request) Successful in 6s
CI / Tests (py3.12 / windows-latest) (pull_request) Has been cancelled
BCC has always been dark-only -- BG #1b1d23, hardcoded at import time, with no light option and no awareness of the desktop's appearance. On a light desktop it matches nothing else on screen and there was no way to change it. Adds a Palette value type in bcc_core with DARK (byte-identical to the colours v1.3.0 shipped) and a new LIGHT, plus resolve_theme(setting, system_is_dark) so the decision is testable without a Qt app. View > Theme offers Match system / Light / Dark, persisted in QSettings under ui/theme, defaulting to following the system. The light palette's semantic colours are deliberately not the dark ones lightened: #4ade80 sits near 1.7:1 against white. They are darkened to clear WCAG AA, and a contrast test enforces >= 4.5:1 for every text colour against its surface in both palettes so nobody harmonises them back later. Three near-black literals were baked into the stylesheet (#1a1205 on-accent text, #202229 disabled table, #16181d diagnostics pane). Fine with one theme, invisible breakage with two -- each now has a palette slot, and a test asserts build_stylesheet contains no hex literals at all. The ~20 inline setStyleSheet(f"color: {MUTED}") call sites are left alone: apply_palette rebinds the module-level colour names, and an f-string resolves its names when it runs, so each call site picks up the new colour on its next render. Switching theme reapplies the global QSS and re-renders the inline-styled widgets, so nothing is left dark-on-light. Refs #75