[PR #2760] feat: add light mode with system/light/dark theme support #2936

Open
opened 2026-10-14 21:06:19 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/amnezia-vpn/amnezia-client/pull/2760
Author: @real-alexei
Created: 6/22/2026
Status: 🔄 Open

Base: dev ← Head: feat/light-mode


📝 Commits (10+)

  • 88ee9cd feat: add light mode with system/light/dark theme support
  • 247e78f feat: add translations for Color theme menu
  • 544ffb6 feat: light-mode switch uses apricot track with white knob
  • 755e842 fix: restore connection-state translations (ConnectionUiController)
  • 93690e8 fix: make notification popup readable in light mode
  • bc949d7 feat: light-mode disabled "on" switch uses muted apricot track
  • 563ecd2 fix: soften protocol chip in light mode and balance its chevron
  • 0616fc3 fix: disabled selected radio title matches the indicator color
  • 42bc209 fix: tint list leading icons so they stay visible in light mode
  • 46afcc2 merge: origin/dev into feat/light-mode

📊 Changes

35 files changed (+886 additions, -52 deletions)

View changed files

📝 client/core/controllers/coreController.cpp (+3 -0)
📝 client/core/controllers/coreController.h (+2 -0)
📝 client/core/controllers/settingsController.cpp (+10 -0)
📝 client/core/controllers/settingsController.h (+3 -0)
📝 client/core/repositories/secureAppSettingsRepository.cpp (+10 -0)
📝 client/core/repositories/secureAppSettingsRepository.h (+3 -0)
📝 client/translations/amneziavpn_ar_EG.ts (+43 -0)
📝 client/translations/amneziavpn_fa_IR.ts (+43 -0)
📝 client/translations/amneziavpn_hi_IN.ts (+43 -0)
📝 client/translations/amneziavpn_my_MM.ts (+43 -0)
📝 client/translations/amneziavpn_ru_RU.ts (+43 -0)
📝 client/translations/amneziavpn_uk_UA.ts (+43 -0)
📝 client/translations/amneziavpn_ur_PK.ts (+43 -0)
📝 client/translations/amneziavpn_zh_CN.ts (+43 -0)
➕ client/ui/controllers/appearanceController.cpp (+73 -0)
➕ client/ui/controllers/appearanceController.h (+37 -0)
📝 client/ui/qml/Components/AddSitePanel.qml (+1 -1)
📝 client/ui/qml/Components/ConnectButton.qml (+2 -1)
➕ client/ui/qml/Components/SelectThemeDrawer.qml (+174 -0)
📝 client/ui/qml/Controls2/BasicButtonType.qml (+5 -5)

...and 15 more files

📄 Description

Add a user-selectable color theme (System / Light / Dark, default System) that follows the OS appearance live, plus the light-mode visual polish and translation fixes that came out of testing it.

Theme support

  • AppearanceController wraps QStyleHints::colorScheme() and resolves the effective theme from a persisted preference (Conf/appTheme).
  • AmneziaStyle becomes theme-aware: dark/light palettes selected by an isDark flag bound from the controller, so every binding re-themes live with no per-call-site changes.
  • Settings → Application gains a "Color theme" picker (SelectThemeDrawer).
  • Light palette: light surfaces, dark text, inverted hover/press overlays, dark modal scrim; #E38E41 accent highlight; apricot primary buttons; the Connect-ring glow is suppressed in light mode.
  • Migrate stray hardcoded colors into the palette so they theme correctly (ChangelogDrawer, NewsDetail, AddSitePanel, SFTP doc links).
  • Redraw VerticalRadioButton indicator as palette-driven shapes; add a themeable leading-icon tint to CardWithIconsType.

Light-mode polish

Issues found while testing the light theme (dark mode stays pixel-identical throughout — all of these are gated to the light palette or use theme-aware palette roles):

  • Switch (SwitcherType): the checked track kept the dark-mode brown, which read heavier than the knob on a light surface. Light mode now shows the conventional look — a solid apricot track with a white knob; the disabled "on" pill uses a muted apricot track.
  • Notification toast (PopupType): the popup had a hardcoded white background with theme-inverting text, so in light mode it rendered white-on-white — an empty white box (e.g. the "Unable to disconnect during configuration preparation" notice). Now a theme-aware notificationBackground: white in dark mode, dark charcoal in light mode, so the message reads and the toast stands out.
  • Home protocol chip (PageHome / DropDownType): the prominent inverted chip went from a light pill (dark mode) to a harsh near-black pill in light mode — softened to charcoal. Also balanced its chevron on the short content-hugging pill (added rootButtonImageRightMargin, default unchanged for other dropdowns).
  • Disabled selected radio: a checked-but-disabled VerticalRadioButton title now matches the pale-apricot indicator instead of burnt orange.

Translations

  • Add Color theme / System / Light / Dark across all 8 locale files (ru, uk, zh_CN, fa, ar, my, ur, hi), in both the PageSettingsApplication and SelectThemeDrawer contexts.
  • Fix a pre-existing localization bug: the connection-state strings ("Connect", "Connecting…", "Connected", "Reconnecting…", "Disconnecting…", "Preparing…") rendered in English. The controller had been refactored ConnectionController → ConnectionUiController, which orphaned their tr() context, so runtime lookups fell back to source text. Re-added a ConnectionUiController context to all 8 locale files, reusing the existing translations.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/amnezia-vpn/amnezia-client/pull/2760 **Author:** [@real-alexei](https://github.com/real-alexei) **Created:** 6/22/2026 **Status:** 🔄 Open **Base:** `dev` ← **Head:** `feat/light-mode` --- ### 📝 Commits (10+) - [`88ee9cd`](https://github.com/amnezia-vpn/amnezia-client/commit/88ee9cdabc1ce34287072869e5c812e59110958c) feat: add light mode with system/light/dark theme support - [`247e78f`](https://github.com/amnezia-vpn/amnezia-client/commit/247e78f7fadc3c1182a5e9ecd99e4a69f705099c) feat: add translations for Color theme menu - [`544ffb6`](https://github.com/amnezia-vpn/amnezia-client/commit/544ffb6010c7f81d8ff7c53e91ce97701f23e986) feat: light-mode switch uses apricot track with white knob - [`755e842`](https://github.com/amnezia-vpn/amnezia-client/commit/755e842db39995ae38ff3810b0e3d69a4d96e3f3) fix: restore connection-state translations (ConnectionUiController) - [`93690e8`](https://github.com/amnezia-vpn/amnezia-client/commit/93690e8663ad55cf74ce5cd8915132bc34c3ddaa) fix: make notification popup readable in light mode - [`bc949d7`](https://github.com/amnezia-vpn/amnezia-client/commit/bc949d76be76ed44b33c69278b8cced05515bc3b) feat: light-mode disabled "on" switch uses muted apricot track - [`563ecd2`](https://github.com/amnezia-vpn/amnezia-client/commit/563ecd21ba7a94cfa5bfa924ea9166bfa074672c) fix: soften protocol chip in light mode and balance its chevron - [`0616fc3`](https://github.com/amnezia-vpn/amnezia-client/commit/0616fc3b9c950ce48f331d5e84a060b730c4a6c1) fix: disabled selected radio title matches the indicator color - [`42bc209`](https://github.com/amnezia-vpn/amnezia-client/commit/42bc2099f5fda95eb14b3deeb41c1d07e895a0fe) fix: tint list leading icons so they stay visible in light mode - [`46afcc2`](https://github.com/amnezia-vpn/amnezia-client/commit/46afcc2dc9692536355d38a1f226bd6331b910c4) merge: origin/dev into feat/light-mode ### 📊 Changes **35 files changed** (+886 additions, -52 deletions) <details> <summary>View changed files</summary> 📝 `client/core/controllers/coreController.cpp` (+3 -0) 📝 `client/core/controllers/coreController.h` (+2 -0) 📝 `client/core/controllers/settingsController.cpp` (+10 -0) 📝 `client/core/controllers/settingsController.h` (+3 -0) 📝 `client/core/repositories/secureAppSettingsRepository.cpp` (+10 -0) 📝 `client/core/repositories/secureAppSettingsRepository.h` (+3 -0) 📝 `client/translations/amneziavpn_ar_EG.ts` (+43 -0) 📝 `client/translations/amneziavpn_fa_IR.ts` (+43 -0) 📝 `client/translations/amneziavpn_hi_IN.ts` (+43 -0) 📝 `client/translations/amneziavpn_my_MM.ts` (+43 -0) 📝 `client/translations/amneziavpn_ru_RU.ts` (+43 -0) 📝 `client/translations/amneziavpn_uk_UA.ts` (+43 -0) 📝 `client/translations/amneziavpn_ur_PK.ts` (+43 -0) 📝 `client/translations/amneziavpn_zh_CN.ts` (+43 -0) ➕ `client/ui/controllers/appearanceController.cpp` (+73 -0) ➕ `client/ui/controllers/appearanceController.h` (+37 -0) 📝 `client/ui/qml/Components/AddSitePanel.qml` (+1 -1) 📝 `client/ui/qml/Components/ConnectButton.qml` (+2 -1) ➕ `client/ui/qml/Components/SelectThemeDrawer.qml` (+174 -0) 📝 `client/ui/qml/Controls2/BasicButtonType.qml` (+5 -5) _...and 15 more files_ </details> ### 📄 Description Add a user-selectable color theme (**System / Light / Dark**, default System) that follows the OS appearance live, plus the light-mode visual polish and translation fixes that came out of testing it. ## Theme support - **AppearanceController** wraps `QStyleHints::colorScheme()` and resolves the effective theme from a persisted preference (`Conf/appTheme`). - **AmneziaStyle** becomes theme-aware: dark/light palettes selected by an `isDark` flag bound from the controller, so every binding re-themes live with no per-call-site changes. - Settings → Application gains a **"Color theme"** picker (`SelectThemeDrawer`). - **Light palette**: light surfaces, dark text, inverted hover/press overlays, dark modal scrim; `#E38E41` accent highlight; apricot primary buttons; the Connect-ring glow is suppressed in light mode. - Migrate stray hardcoded colors into the palette so they theme correctly (ChangelogDrawer, NewsDetail, AddSitePanel, SFTP doc links). - Redraw `VerticalRadioButton` indicator as palette-driven shapes; add a themeable leading-icon tint to `CardWithIconsType`. ## Light-mode polish Issues found while testing the light theme (dark mode stays pixel-identical throughout — all of these are gated to the light palette or use theme-aware palette roles): - **Switch** (`SwitcherType`): the checked track kept the dark-mode brown, which read heavier than the knob on a light surface. Light mode now shows the conventional look — a solid apricot track with a white knob; the disabled "on" pill uses a muted apricot track. - **Notification toast** (`PopupType`): the popup had a hardcoded white background with theme-inverting text, so in light mode it rendered white-on-white — an empty white box (e.g. the "Unable to disconnect during configuration preparation" notice). Now a theme-aware `notificationBackground`: white in dark mode, dark charcoal in light mode, so the message reads and the toast stands out. - **Home protocol chip** (`PageHome` / `DropDownType`): the prominent inverted chip went from a light pill (dark mode) to a harsh near-black pill in light mode — softened to charcoal. Also balanced its chevron on the short content-hugging pill (added `rootButtonImageRightMargin`, default unchanged for other dropdowns). - **Disabled selected radio**: a checked-but-disabled `VerticalRadioButton` title now matches the pale-apricot indicator instead of burnt orange. ## Translations - Add **Color theme / System / Light / Dark** across all 8 locale files (ru, uk, zh_CN, fa, ar, my, ur, hi), in both the `PageSettingsApplication` and `SelectThemeDrawer` contexts. - **Fix a pre-existing localization bug**: the connection-state strings ("Connect", "Connecting…", "Connected", "Reconnecting…", "Disconnecting…", "Preparing…") rendered in English. The controller had been refactored `ConnectionController` → `ConnectionUiController`, which orphaned their `tr()` context, so runtime lookups fell back to source text. Re-added a `ConnectionUiController` context to all 8 locale files, reusing the existing translations. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amnezia-vpn/amnezia-client#2936
No description provided.