Linux_x86_64_cpu_only_Ubuntu_UI0.1_Major
NativeLab Pro — UI Theme Changelog
All changes relate to the dual light/dark theme system, appearance consistency, and the live Theme Editor tab introduced during this session.
Phase 1 — Dual Theme Architecture (Initial Implementation)
Added the foundational infrastructure to support runtime theme switching.
- Added
CURRENT_THEME = "light"global variable to track active theme state. - Split the single
Ccolour dictionary intoC_DARK(original palette) andC_LIGHT(new light palette), withCassigned dynamically based onCURRENT_THEME. - Converted the static
QSSstylesheet string into a_build_qss(c: dict)function so the stylesheet can be regenerated from any palette at runtime. - Added a View → Switch to Light/Dark Theme menu item with a dynamic label that updates to reflect the current state.
- Implemented
_toggle_theme()and_update_theme_action_label()methods onMainWindow. - Added theme persistence: the active theme is saved to
app_config.jsonand restored on next launch.
Initial C_LIGHT palette
The first iteration used a warm cream aesthetic: #faf7f2 canvas, sage green #4a7652 accent, and warm brown #1c1810 text.
Phase 2 — Professional Light Palette (Stripe/Linear aesthetic)
Replaced the cream/sage palette with a clinical, high-contrast SaaS-style palette after user feedback that the initial version looked unprofessional.
Key values introduced:
| Token | Value | Purpose |
|---|---|---|
| bg0 | #ffffff | Pure white canvas |
| bg1 | #f7f7f8 | Sidebar/panel |
| acc | #2563eb | Vivid blue accent (Stripe standard) |
| txt | #0d0d10 | Near-black primary text |
| bdr | #e4e4e7 | Barely-there zinc-200 border |
| usr | #eff6ff | Whisper-blue user bubble |
All warm-neutral tones; no cool greys. Accent colour shifted from blue to burnt orange to harmonise with the peach base.
Phase 7 — Live Appearance / Theme Editor Tab
Added a full 🎨 Appearance tab allowing users to edit every colour token of the active theme in real time using colour swatches, hex inputs, and HSL sliders.
New class: AppearanceTab(QWidget)
- Emits
theme_changed = pyqtSignal(dict)whenever any colour is modified. - Colour tokens are grouped into six logical sections: Backgrounds, Text, Accent, Bubbles, Borders, Semantic.
- Each token row contains: a labelled swatch button (opens
QColorDialog), a hexQLineEdit, and three HSLQSliderwidgets (Hue 0–360, Saturation 0–100, Lightness 0–100). - All three controls stay in sync — editing one updates the others.
- Reset button reverts to the current built-in palette for the active theme.
- Save button persists the custom palette to
app_config.json.
Separate persistence per theme
- Light mode saves to
APP_CONFIG["custom_light_palette"]. - Dark mode saves to
APP_CONFIG["custom_dark_palette"]. - Both are loaded and merged at startup independently, so customising one theme does not affect the other.
QSS additions for Appearance tab
Added rules for: #appearance_bar, #appearance_hdr, #appearance_group_hdr, #appearance_row_lbl, #appearance_sl_lbl, QLineEdit#appearance_hex, QSlider#appearance_slider (groove, handle, sub-page), QPushButton#appearance_btn, QPushButton#appearance_btn_acc.
MainWindow wiring
AppearanceTabis instantiated in_build_uiand wired viatheme_changed → _on_appearance_changed._on_appearance_changedupdatesC_LIGHTorC_DARK(whichever is active), rebuildsQSS, and callsself.setStyleSheet(QSS)— changes are visible instantly without restarting._toggle_themecallsappearance_tab.load_palette(...)after switching so the editor always reflects the current theme's colours.- Palette loading at startup was moved into
__init__after_build_uireturns, so it executes afterQApplicationis fully initialised.
setStyleSheet migration
All QApplication.instance().setStyleSheet(QSS) calls were replaced with self.setStyleSheet(QSS) on the QMainWindow instance to avoid NoneType errors during initialisation. Stylesheet inheritance from the top-level window to all child widgets is identical.
End of changelog.