From b003976d3954c3e825c8dfef1284cf3a8beb05f7 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Thu, 21 May 2026 16:51:37 -0400 Subject: [PATCH] =?UTF-8?q?theme:=20upgrade=20palette=20from=20Catppuccin?= =?UTF-8?q?=20Mocha=20to=20Frapp=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces all dark-Mocha colours (#1e1e2e base, #313244 surface0, etc.) with the noticeably brighter Frappé variants (#303446 base, #414559 surface0, etc.) across the QSS and every hardcoded colour in Python source files (syntax highlighter, completer popup, log viewer, explain view, table viewer, schema browser, icons, etc.). Co-Authored-By: Claude Sonnet 4.6 --- app/models/connection_model.py | 4 +- app/models/result_table_model.py | 2 +- app/ui/connection_dialog.py | 4 +- app/ui/explain_view.py | 22 +-- app/ui/log_viewer.py | 18 +- app/ui/query_history.py | 2 +- app/ui/schema_browser.py | 8 +- app/ui/sql_completer.py | 12 +- app/ui/sql_editor.py | 8 +- app/ui/syntax_highlighter.py | 22 +-- app/ui/table_structure.py | 4 +- app/ui/table_viewer.py | 12 +- app/utils/icons.py | 2 +- resources/style.qss | 322 +++++++++++++++---------------- 14 files changed, 221 insertions(+), 221 deletions(-) diff --git a/app/models/connection_model.py b/app/models/connection_model.py index 58177ad..d8c71f6 100644 --- a/app/models/connection_model.py +++ b/app/models/connection_model.py @@ -14,7 +14,7 @@ class ConnectionProfile: database: str = "" username: str = "" password: str = field(default="", repr=False) - color: str = "#89b4fa" + color: str = "#8caaee" id: str = field(default_factory=lambda: str(uuid.uuid4())) ssl: bool = False ssl_cert: str = "" @@ -71,7 +71,7 @@ class ConnectionProfile: port=data.get("port", 3306), database=data.get("database", ""), username=data.get("username", ""), - color=data.get("color", "#89b4fa"), + color=data.get("color", "#8caaee"), ssl=data.get("ssl", False), ssl_cert=data.get("ssl_cert", ""), ssl_key=data.get("ssl_key", ""), diff --git a/app/models/result_table_model.py b/app/models/result_table_model.py index 254ff9c..0a02e0b 100644 --- a/app/models/result_table_model.py +++ b/app/models/result_table_model.py @@ -11,7 +11,7 @@ from PyQt6.QtGui import QColor, QFont class ResultTableModel(QAbstractTableModel): """Immutable result-set model — replaces data via set_data().""" - NULL_COLOR = QColor("#6c7086") # muted grey for NULL + NULL_COLOR = QColor("#737994") # muted grey for NULL NUM_ALIGN = Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter TEXT_ALIGN = Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter diff --git a/app/ui/connection_dialog.py b/app/ui/connection_dialog.py index d713c1a..909a62f 100644 --- a/app/ui/connection_dialog.py +++ b/app/ui/connection_dialog.py @@ -17,7 +17,7 @@ from app.config.connections import save_profile class ColorButton(QPushButton): """A button that shows a solid colour and opens a colour picker.""" - def __init__(self, color: str = "#89b4fa", parent=None): + def __init__(self, color: str = "#8caaee", parent=None): super().__init__(parent) self._color = color self.setFixedSize(32, 24) @@ -26,7 +26,7 @@ class ColorButton(QPushButton): def _refresh(self): self.setStyleSheet( - f"background-color:{self._color}; border:1px solid #45475a; border-radius:4px;" + f"background-color:{self._color}; border:1px solid #51576d; border-radius:4px;" ) def _pick(self): diff --git a/app/ui/explain_view.py b/app/ui/explain_view.py index 657c4e8..91cfc6a 100644 --- a/app/ui/explain_view.py +++ b/app/ui/explain_view.py @@ -36,12 +36,12 @@ def _cost_color(val_str: str) -> QColor: try: v = float(str(val_str).replace(",", "")) except (ValueError, TypeError): - return QColor("#cdd6f4") # neutral (Catppuccin text) + return QColor("#c6d0f5") # neutral (Catppuccin text) if v <= 10: - return QColor("#a6e3a1") # green — cheap + return QColor("#a6d189") # green — cheap if v <= 1_000: - return QColor("#f9e2af") # yellow — moderate - return QColor("#f38ba8") # red — expensive + return QColor("#e5c890") # yellow — moderate + return QColor("#e78284") # red — expensive # ── Background worker ───────────────────────────────────────────────────────── @@ -101,9 +101,9 @@ def _build_mysql_tree(tree: QTreeWidget, cols: list, rows: list): good_types = {"const", "eq_ref", "ref", "system"} jt_lower = join_type.lower() if jt_lower in bad_types: - item.setForeground(1, QBrush(QColor("#f38ba8"))) + item.setForeground(1, QBrush(QColor("#e78284"))) elif jt_lower in good_types: - item.setForeground(1, QBrush(QColor("#a6e3a1"))) + item.setForeground(1, QBrush(QColor("#a6d189"))) # Colour rows estimate item.setForeground(3, QBrush(_cost_color(est_rows))) @@ -203,9 +203,9 @@ def _build_sqlite_tree(tree: QTreeWidget, cols: list, rows: list): # Colour SCAN (bad) vs SEARCH/INDEX (good) detail_str = str(detail).upper() if "SCAN" in detail_str and "INDEX" not in detail_str: - item.setForeground(1, QBrush(QColor("#f38ba8"))) + item.setForeground(1, QBrush(QColor("#e78284"))) elif "INDEX" in detail_str or "SEARCH" in detail_str: - item.setForeground(1, QBrush(QColor("#a6e3a1"))) + item.setForeground(1, QBrush(QColor("#a6d189"))) items[rid] = item parent_item = items.get(parent) @@ -334,8 +334,8 @@ class ExplainPanel(QWidget): legend_row = QHBoxLayout() legend_row.setContentsMargins(8, 2, 0, 4) for colour, label in [ - ("#a6e3a1", "Efficient"), ("#f9e2af", "Moderate"), - ("#f38ba8", "Expensive / SCAN"), + ("#a6d189", "Efficient"), ("#e5c890", "Moderate"), + ("#e78284", "Expensive / SCAN"), ]: dot = QLabel("●") dot.setStyleSheet(f"color: {colour};") @@ -414,7 +414,7 @@ class ExplainPanel(QWidget): self._status_lbl.setText(f"Error: {msg[:80]}") self._tree.clear() err_item = QTreeWidgetItem([f"⚠ {msg}"]) - err_item.setForeground(0, QBrush(QColor("#f38ba8"))) + err_item.setForeground(0, QBrush(QColor("#e78284"))) self._tree.setColumnCount(1) self._tree.setHeaderLabels(["Error"]) self._tree.addTopLevelItem(err_item) diff --git a/app/ui/log_viewer.py b/app/ui/log_viewer.py index f459d08..ef3e20e 100644 --- a/app/ui/log_viewer.py +++ b/app/ui/log_viewer.py @@ -30,14 +30,14 @@ from PyQt6.QtGui import ( from app.utils.logger import get_log_path -# ── Level colours (Catppuccin Mocha palette) ────────────────────────────────── +# ── Level colours (Catppuccin Frappé palette) ───────────────────────────────── _LEVEL_COLOURS: dict[str, str] = { - "DEBUG": "#6c7086", # surface2 / dimmed - "INFO": "#cdd6f4", # text (default) - "WARNING": "#f9e2af", # yellow - "ERROR": "#f38ba8", # red - "CRITICAL": "#ff79c6", # pink / bright red + "DEBUG": "#737994", # overlay0 / dimmed + "INFO": "#c6d0f5", # text (default) + "WARNING": "#e5c890", # yellow + "ERROR": "#e78284", # red + "CRITICAL": "#f4b8e4", # pink / bright } _LEVEL_ORDER = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] @@ -85,8 +85,8 @@ class _LogHighlighter(QSyntaxHighlighter): # Highlight search matches in bright yellow if self._search: search_fmt = QTextCharFormat() - search_fmt.setBackground(QColor("#f9e2af")) - search_fmt.setForeground(QColor("#1e1e2e")) + search_fmt.setBackground(QColor("#e5c890")) + search_fmt.setForeground(QColor("#303446")) idx = text.lower().find(self._search) while idx != -1: self.setFormat(idx, len(self._search), search_fmt) @@ -107,7 +107,7 @@ class _LevelBtn(QPushButton): def _apply_style(self, checked: bool): if checked: self.setStyleSheet( - f"QPushButton {{ background: {self._colour}; color: #1e1e2e; " + f"QPushButton {{ background: {self._colour}; color: #303446; " f"border: none; border-radius: 3px; font-weight: bold; }}" ) else: diff --git a/app/ui/query_history.py b/app/ui/query_history.py index 2fd175c..fdcf77f 100644 --- a/app/ui/query_history.py +++ b/app/ui/query_history.py @@ -153,7 +153,7 @@ class QueryHistoryPanel(QWidget): for c, val in enumerate(items): item = QTableWidgetItem(val) if c == 3 and status == "ERROR": - item.setForeground(QColor("#f38ba8")) + item.setForeground(QColor("#e78284")) self._table.setItem(r, c, item) def _filter(self, text: str): diff --git a/app/ui/schema_browser.py b/app/ui/schema_browser.py index 8b9ca48..032138c 100644 --- a/app/ui/schema_browser.py +++ b/app/ui/schema_browser.py @@ -96,7 +96,7 @@ class SchemaBrowser(QWidget): # Dim colour — show the profile colour but muted color = QColor(profile.color) color.setAlpha(140) - item.setForeground(0, QBrush(QColor("#6c7086"))) # greyed out + item.setForeground(0, QBrush(QColor("#737994"))) # greyed out item.setIcon(0, get_icon(profile.db_type, 16)) item.setToolTip(0, self._connection_tooltip(profile)) @@ -350,9 +350,9 @@ class SchemaBrowser(QWidget): child = QTreeWidgetItem([label]) child.setData(0, Qt.ItemDataRole.UserRole, (NT["column"], "", "", c.name)) if c.is_primary_key: - child.setForeground(0, QBrush(QColor("#f9e2af"))) + child.setForeground(0, QBrush(QColor("#e5c890"))) elif c.is_foreign_key: - child.setForeground(0, QBrush(QColor("#89dceb"))) + child.setForeground(0, QBrush(QColor("#99d1db"))) item.addChild(child) def _load_indexes(self, item, pid, db, table): @@ -386,7 +386,7 @@ class SchemaBrowser(QWidget): def _show_error(self, item, msg): err = QTreeWidgetItem([f"❌ {msg}"]) - err.setForeground(0, QBrush(QColor("#f38ba8"))) + err.setForeground(0, QBrush(QColor("#e78284"))) item.addChild(err) # ── Context menu ────────────────────────────────────────────────────────── diff --git a/app/ui/sql_completer.py b/app/ui/sql_completer.py index 9424332..f0c2a2c 100644 --- a/app/ui/sql_completer.py +++ b/app/ui/sql_completer.py @@ -53,19 +53,19 @@ class _CompletionPopup(QListWidget): self.setStyleSheet(""" QListWidget { - background: #1e1e2e; - color: #cdd6f4; - border: 1px solid #45475a; + background: #292c3c; + color: #c6d0f5; + border: 1px solid #51576d; border-radius: 4px; padding: 2px; outline: none; } QListWidget::item { padding: 2px 8px; } QListWidget::item:selected { - background: #313244; - color: #cdd6f4; + background: #414559; + color: #c6d0f5; } - QListWidget::item:hover { background: #2a2a3c; } + QListWidget::item:hover { background: #363a4f; } """) self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded) self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) diff --git a/app/ui/sql_editor.py b/app/ui/sql_editor.py index e717934..984499f 100644 --- a/app/ui/sql_editor.py +++ b/app/ui/sql_editor.py @@ -81,7 +81,7 @@ class CodeEditor(QPlainTextEdit): extra = [] if not self.isReadOnly(): sel = QTextEdit.ExtraSelection() - sel.format.setBackground(QColor("#2a2a3c")) + sel.format.setBackground(QColor("#3d4155")) sel.format.setProperty(QTextFormat.Property.FullWidthSelection, True) sel.cursor = self.textCursor() sel.cursor.clearSelection() @@ -90,7 +90,7 @@ class CodeEditor(QPlainTextEdit): def line_number_area_paint_event(self, event): painter = QPainter(self._line_area) - painter.fillRect(event.rect(), QColor("#1a1a2e")) + painter.fillRect(event.rect(), QColor("#2a2d3e")) block = self.firstVisibleBlock() number = block.blockNumber() @@ -100,7 +100,7 @@ class CodeEditor(QPlainTextEdit): while block.isValid() and top <= event.rect().bottom(): if block.isVisible() and bottom >= event.rect().top(): - painter.setPen(QColor("#45475a")) + painter.setPen(QColor("#51576d")) painter.drawText( 0, top, self._line_area.width() - 6, self.fontMetrics().height(), @@ -339,7 +339,7 @@ class FindBar(QWidget): self._do_find(backward=True) def _set_no_match(self, no_match: bool): - color = "#f38ba8" if no_match else "" + color = "#e78284" if no_match else "" self._find_input.setStyleSheet( f"background: {color};" if no_match else "" ) diff --git a/app/ui/syntax_highlighter.py b/app/ui/syntax_highlighter.py index 345b7f5..b6c90ef 100644 --- a/app/ui/syntax_highlighter.py +++ b/app/ui/syntax_highlighter.py @@ -17,15 +17,15 @@ def _fmt(color: str, bold: bool = False, italic: bool = False) -> QTextCharForma return f -# ── Token categories (Catppuccin Mocha palette) ─────────────────────────────── -_KEYWORD_FMT = _fmt("#89b4fa", bold=True) # blue — DDL/DML/control -_TYPE_FMT = _fmt("#fab387") # peach — data types -_FUNCTION_FMT = _fmt("#a6e3a1") # green — functions -_STRING_FMT = _fmt("#a6e3a1") # green — string literals -_NUMBER_FMT = _fmt("#fab387") # orange — numeric literals -_COMMENT_FMT = _fmt("#6c7086", italic=True) # grey — comments -_OPERATOR_FMT = _fmt("#cba6f7") # mauve — operators/special -_STAR_FMT = _fmt("#cba6f7", bold=True) # mauve — * wildcard +# ── Token categories (Catppuccin Frappé palette) ───────────────────────────── +_KEYWORD_FMT = _fmt("#8caaee", bold=True) # blue — DDL/DML/control +_TYPE_FMT = _fmt("#ef9f76") # peach — data types +_FUNCTION_FMT = _fmt("#a6d189") # green — functions +_STRING_FMT = _fmt("#a6d189") # green — string literals +_NUMBER_FMT = _fmt("#ef9f76") # orange — numeric literals +_COMMENT_FMT = _fmt("#737994", italic=True) # grey — comments +_OPERATOR_FMT = _fmt("#ca9ee6") # mauve — operators/special +_STAR_FMT = _fmt("#ca9ee6", bold=True) # mauve — * wildcard # ── Keyword lists ───────────────────────────────────────────────────────────── _KEYWORDS = [ @@ -101,9 +101,9 @@ class SQLHighlighter(QSyntaxHighlighter): # Single-quoted strings (QRegularExpression(r"'[^'\\]*(?:\\.[^'\\]*)*'"), _STRING_FMT), # Double-quoted identifiers - (QRegularExpression(r'"[^"]*"'), _fmt("#89dceb")), + (QRegularExpression(r'"[^"]*"'), _fmt("#99d1db")), # Backtick identifiers (MySQL) - (QRegularExpression(r"`[^`]*`"), _fmt("#89dceb")), + (QRegularExpression(r"`[^`]*`"), _fmt("#99d1db")), # * wildcard (QRegularExpression(r"\bSELECT\s+\*|\*(?=\s*FROM)", QRegularExpression.PatternOption.CaseInsensitiveOption), diff --git a/app/ui/table_structure.py b/app/ui/table_structure.py index c8e4065..4a1581f 100644 --- a/app/ui/table_structure.py +++ b/app/ui/table_structure.py @@ -171,9 +171,9 @@ class TableStructureView(QWidget): item = QTableWidgetItem(str(val)) item.setTextAlignment(Qt.AlignmentFlag.AlignCenter) if col.is_primary_key and c == 0: - item.setForeground(QColor("#f9e2af")) + item.setForeground(QColor("#e5c890")) elif col.is_foreign_key and c == 0: - item.setForeground(QColor("#89dceb")) + item.setForeground(QColor("#99d1db")) t.setItem(r, c, item) def _load_indexes(self): diff --git a/app/ui/table_viewer.py b/app/ui/table_viewer.py index 3daa226..c66953a 100644 --- a/app/ui/table_viewer.py +++ b/app/ui/table_viewer.py @@ -148,17 +148,17 @@ class EditableTableModel(QAbstractTableModel): if role == Qt.ItemDataRole.ForegroundRole: if self._is_deleted_row(r): - return QBrush(QColor("#f38ba8")) # red — pending delete + return QBrush(QColor("#e78284")) # red — pending delete if (r, c) in self._dirty: - return QBrush(QColor("#fab387")) # orange — edited + return QBrush(QColor("#ef9f76")) # orange — edited if val is None: - return QBrush(QColor("#6c7086")) # grey — NULL + return QBrush(QColor("#737994")) # grey — NULL if role == Qt.ItemDataRole.BackgroundRole: if self._is_deleted_row(r): - return QBrush(QColor("#2a1a1e")) + return QBrush(QColor("#3a2530")) if (r, c) in self._dirty: - return QBrush(QColor("#2a1f1a")) + return QBrush(QColor("#3a2f25")) return None @@ -351,7 +351,7 @@ class TableViewer(QWidget): # Separator sep = QLabel("|") - sep.setStyleSheet("color:#45475a; padding:0 4px;") + sep.setStyleSheet("color:#51576d; padding:0 4px;") # CRUD buttons self._add_btn = QPushButton("➕ Add") diff --git a/app/utils/icons.py b/app/utils/icons.py index 4a06632..3b487a0 100644 --- a/app/utils/icons.py +++ b/app/utils/icons.py @@ -64,7 +64,7 @@ ICONS = { def make_icon(glyph: str, size: int = 20, - fg: str = "#cdd6f4", bg: str = "transparent") -> QIcon: + fg: str = "#c6d0f5", bg: str = "transparent") -> QIcon: """Create a QIcon from a Unicode glyph.""" px = QPixmap(QSize(size, size)) px.fill(Qt.GlobalColor.transparent) diff --git a/resources/style.qss b/resources/style.qss index 5ca5722..49a0382 100644 --- a/resources/style.qss +++ b/resources/style.qss @@ -1,15 +1,15 @@ /* ═══════════════════════════════════════════════════════════════════════════ - DBClient — Dark Theme (Catppuccin Mocha palette) + DBClient — Dark Theme (Catppuccin Frappé palette) ═══════════════════════════════════════════════════════════════════════════ */ /* ── Variables via flat tokens ───────────────────────────────────────────── - base #1e1e2e crust #11111b - surface0 #313244 surface1 #45475a surface2 #585b70 - overlay #6c7086 subtext #a6adc8 text #cdd6f4 - blue #89b4fa lavender #b4befe sapphire #74c7ec - green #a6e3a1 teal #94e2d5 sky #89dceb - mauve #cba6f7 pink #f5c2e7 red #f38ba8 - peach #fab387 yellow #f9e2af + base #303446 crust #232634 + surface0 #414559 surface1 #51576d surface2 #626880 + overlay #737994 subtext #a5adce text #c6d0f5 + blue #8caaee lavender #babbf1 sapphire #85c1dc + green #a6d189 teal #81c8be sky #99d1db + mauve #ca9ee6 pink #f4b8e4 red #e78284 + peach #ef9f76 yellow #e5c890 ─────────────────────────────────────────────────────────────────────── */ /* ── Global reset ───────────────────────────────────────────────────────── */ @@ -18,22 +18,22 @@ } QMainWindow, QDialog { - background-color: #1e1e2e; - color: #cdd6f4; + background-color: #303446; + color: #c6d0f5; } QWidget { - background-color: #1e1e2e; - color: #cdd6f4; + background-color: #303446; + color: #c6d0f5; font-family: "Segoe UI", "Inter", sans-serif; font-size: 10pt; } /* ── Menu bar ───────────────────────────────────────────────────────────── */ QMenuBar { - background-color: #11111b; - color: #cdd6f4; - border-bottom: 1px solid #313244; + background-color: #232634; + color: #c6d0f5; + border-bottom: 1px solid #414559; padding: 2px 0; } @@ -43,12 +43,12 @@ QMenuBar::item { } QMenuBar::item:selected { - background-color: #313244; + background-color: #414559; } QMenu { - background-color: #181825; - border: 1px solid #45475a; + background-color: #292c3c; + border: 1px solid #51576d; border-radius: 6px; padding: 4px; } @@ -56,59 +56,59 @@ QMenu { QMenu::item { padding: 6px 24px 6px 12px; border-radius: 4px; - color: #cdd6f4; + color: #c6d0f5; } QMenu::item:selected { - background-color: #313244; - color: #cdd6f4; + background-color: #414559; + color: #c6d0f5; } QMenu::separator { height: 1px; - background: #45475a; + background: #51576d; margin: 4px 8px; } /* ── Status bar ─────────────────────────────────────────────────────────── */ QStatusBar { - background-color: #11111b; - border-top: 1px solid #313244; - color: #a6adc8; + background-color: #232634; + border-top: 1px solid #414559; + color: #a5adce; font-size: 9pt; padding: 2px 8px; } /* ── Scrollbars ─────────────────────────────────────────────────────────── */ QScrollBar:vertical { - background: #1e1e2e; + background: #303446; width: 10px; margin: 0; } QScrollBar::handle:vertical { - background: #45475a; + background: #51576d; border-radius: 5px; min-height: 24px; } QScrollBar::handle:vertical:hover { - background: #585b70; + background: #626880; } QScrollBar:horizontal { - background: #1e1e2e; + background: #303446; height: 10px; } QScrollBar::handle:horizontal { - background: #45475a; + background: #51576d; border-radius: 5px; min-width: 24px; } QScrollBar::handle:horizontal:hover { - background: #585b70; + background: #626880; } QScrollBar::add-line, QScrollBar::sub-line { height: 0; width: 0; } @@ -116,47 +116,47 @@ QScrollBar::add-page, QScrollBar::sub-page { background: transparent; } /* ── Splitter ────────────────────────────────────────────────────────────── */ QSplitter::handle { - background-color: #313244; + background-color: #414559; } QSplitter::handle:horizontal { width: 2px; } QSplitter::handle:vertical { height: 2px; } QSplitter::handle:hover { - background-color: #89b4fa; + background-color: #8caaee; } /* ── Sidebar ─────────────────────────────────────────────────────────────── */ #sidebarHeader { - background-color: #181825; - border-bottom: 1px solid #313244; + background-color: #292c3c; + border-bottom: 1px solid #414559; } #sidebarTitle { - color: #89b4fa; + color: #8caaee; font-size: 11pt; font-weight: 600; } #newConnBtn { - background-color: #313244; - color: #89b4fa; - border: 1px solid #45475a; + background-color: #414559; + color: #8caaee; + border: 1px solid #51576d; border-radius: 6px; font-size: 14pt; padding: 0; } #newConnBtn:hover { - background-color: #45475a; - color: #b4befe; + background-color: #51576d; + color: #babbf1; } /* ── Tree widget ─────────────────────────────────────────────────────────── */ QTreeWidget { - background-color: #181825; + background-color: #292c3c; border: none; - color: #cdd6f4; + color: #c6d0f5; font-size: 10pt; show-decoration-selected: 1; } @@ -167,12 +167,12 @@ QTreeWidget::item { } QTreeWidget::item:hover { - background-color: #2a2a3c; + background-color: #363a4f; } QTreeWidget::item:selected { - background-color: #313244; - color: #cdd6f4; + background-color: #414559; + color: #c6d0f5; } QTreeWidget::branch { @@ -182,32 +182,32 @@ QTreeWidget::branch { /* ── Tab widget ──────────────────────────────────────────────────────────── */ QTabWidget::pane { border: none; - border-top: 1px solid #313244; - background-color: #1e1e2e; + border-top: 1px solid #414559; + background-color: #303446; } QTabBar { - background-color: #181825; + background-color: #292c3c; } QTabBar::tab { - background-color: #181825; - color: #a6adc8; + background-color: #292c3c; + color: #a5adce; padding: 7px 16px; border: none; - border-right: 1px solid #313244; + border-right: 1px solid #414559; font-size: 10pt; } QTabBar::tab:selected { - background-color: #1e1e2e; - color: #cdd6f4; - border-bottom: 2px solid #89b4fa; + background-color: #303446; + color: #c6d0f5; + border-bottom: 2px solid #8caaee; } QTabBar::tab:hover:!selected { - background-color: #252536; - color: #cdd6f4; + background-color: #353849; + color: #c6d0f5; } QTabBar::close-button { @@ -217,13 +217,13 @@ QTabBar::close-button { /* ── Table view ──────────────────────────────────────────────────────────── */ QTableView, QTableWidget { - background-color: #1e1e2e; - alternate-background-color: #252538; - gridline-color: #313244; - color: #cdd6f4; + background-color: #303446; + alternate-background-color: #363a4f; + gridline-color: #414559; + color: #c6d0f5; border: none; - selection-background-color: #313244; - selection-color: #cdd6f4; + selection-background-color: #414559; + selection-color: #c6d0f5; font-size: 10pt; } @@ -232,29 +232,29 @@ QTableView::item, QTableWidget::item { } QHeaderView { - background-color: #181825; + background-color: #292c3c; } QHeaderView::section { - background-color: #181825; - color: #89b4fa; + background-color: #292c3c; + color: #8caaee; border: none; - border-right: 1px solid #313244; - border-bottom: 1px solid #313244; + border-right: 1px solid #414559; + border-bottom: 1px solid #414559; padding: 4px 8px; font-weight: 600; } QHeaderView::section:hover { - background-color: #252536; + background-color: #353849; } /* ── Plain text edit (SQL editor body) ───────────────────────────────────── */ QPlainTextEdit { - background-color: #1e1e2e; - color: #cdd6f4; + background-color: #303446; + color: #c6d0f5; border: none; - selection-background-color: #45475a; + selection-background-color: #51576d; font-family: "Consolas", "JetBrains Mono", "Courier New", monospace; font-size: 13pt; line-height: 1.5; @@ -262,126 +262,126 @@ QPlainTextEdit { /* ── Line number gutter ──────────────────────────────────────────────────── */ LineNumberArea { - background-color: #1a1a2e; + background-color: #2a2d3e; } /* ── Buttons ─────────────────────────────────────────────────────────────── */ QPushButton { - background-color: #313244; - color: #cdd6f4; - border: 1px solid #45475a; + background-color: #414559; + color: #c6d0f5; + border: 1px solid #51576d; border-radius: 6px; padding: 5px 14px; font-size: 10pt; } QPushButton:hover { - background-color: #45475a; - border-color: #585b70; + background-color: #51576d; + border-color: #626880; } QPushButton:pressed { - background-color: #252536; + background-color: #363849; } QPushButton:disabled { - color: #585b70; - background-color: #252536; - border-color: #313244; + color: #626880; + background-color: #363849; + border-color: #414559; } #runBtn { - background-color: #a6e3a1; - color: #1e1e2e; + background-color: #a6d189; + color: #303446; font-weight: 700; border: none; } #runBtn:hover { - background-color: #94e2d5; + background-color: #81c8be; } #stopBtn { - background-color: #f38ba8; - color: #1e1e2e; + background-color: #e78284; + color: #303446; font-weight: 700; border: none; } #stopBtn:hover { - background-color: #eba0ac; + background-color: #ea999c; } #commitBtn { - background-color: #a6e3a1; - color: #1e1e2e; + background-color: #a6d189; + color: #303446; font-weight: 700; border: none; } #rollbackBtn { - background-color: #fab387; - color: #1e1e2e; + background-color: #ef9f76; + color: #303446; font-weight: 700; border: none; } #crudAddBtn { - background-color: #313244; - color: #a6e3a1; - border: 1px solid #a6e3a1; + background-color: #414559; + color: #a6d189; + border: 1px solid #a6d189; font-weight: 600; } #crudAddBtn:hover { - background-color: #a6e3a1; - color: #1e1e2e; + background-color: #a6d189; + color: #303446; } #crudDeleteBtn { - background-color: #313244; - color: #f38ba8; - border: 1px solid #f38ba8; + background-color: #414559; + color: #e78284; + border: 1px solid #e78284; font-weight: 600; } #crudDeleteBtn:hover { - background-color: #f38ba8; - color: #1e1e2e; + background-color: #e78284; + color: #303446; } /* ── Line edit ───────────────────────────────────────────────────────────── */ QLineEdit { - background-color: #313244; - color: #cdd6f4; - border: 1px solid #45475a; + background-color: #414559; + color: #c6d0f5; + border: 1px solid #51576d; border-radius: 6px; padding: 5px 10px; font-size: 10pt; - selection-background-color: #89b4fa; - selection-color: #1e1e2e; + selection-background-color: #8caaee; + selection-color: #303446; } QLineEdit:focus { - border-color: #89b4fa; + border-color: #8caaee; } QLineEdit::placeholder { - color: #585b70; + color: #626880; } /* ── Combo box ───────────────────────────────────────────────────────────── */ QComboBox { - background-color: #313244; - color: #cdd6f4; - border: 1px solid #45475a; + background-color: #414559; + color: #c6d0f5; + border: 1px solid #51576d; border-radius: 6px; padding: 5px 10px; font-size: 10pt; } QComboBox:focus { - border-color: #89b4fa; + border-color: #8caaee; } QComboBox::drop-down { @@ -390,25 +390,25 @@ QComboBox::drop-down { } QComboBox QAbstractItemView { - background-color: #181825; - color: #cdd6f4; - border: 1px solid #45475a; - selection-background-color: #313244; + background-color: #292c3c; + color: #c6d0f5; + border: 1px solid #51576d; + selection-background-color: #414559; } /* ── Spin box ────────────────────────────────────────────────────────────── */ QSpinBox { - background-color: #313244; - color: #cdd6f4; - border: 1px solid #45475a; + background-color: #414559; + color: #c6d0f5; + border: 1px solid #51576d; border-radius: 6px; padding: 4px 8px; } -QSpinBox:focus { border-color: #89b4fa; } +QSpinBox:focus { border-color: #8caaee; } QSpinBox::up-button, QSpinBox::down-button { - background-color: #45475a; + background-color: #51576d; border: none; border-radius: 3px; width: 16px; @@ -416,26 +416,26 @@ QSpinBox::up-button, QSpinBox::down-button { /* ── Check box ───────────────────────────────────────────────────────────── */ QCheckBox { - color: #cdd6f4; + color: #c6d0f5; spacing: 8px; } QCheckBox::indicator { width: 16px; height: 16px; - border: 2px solid #45475a; + border: 2px solid #51576d; border-radius: 4px; - background: #313244; + background: #414559; } QCheckBox::indicator:checked { - background-color: #89b4fa; - border-color: #89b4fa; + background-color: #8caaee; + border-color: #8caaee; } /* ── Dialog ──────────────────────────────────────────────────────────────── */ QDialog { - background-color: #1e1e2e; + background-color: #303446; } QDialogButtonBox QPushButton { @@ -444,22 +444,22 @@ QDialogButtonBox QPushButton { /* ── Form layout labels ──────────────────────────────────────────────────── */ QFormLayout QLabel { - color: #a6adc8; + color: #a5adce; } /* ── Tab widget in dialogs ───────────────────────────────────────────────── */ QTabWidget#dialogTabs::pane { - border: 1px solid #313244; + border: 1px solid #414559; border-radius: 6px; margin-top: -1px; } /* ── Group box ───────────────────────────────────────────────────────────── */ QGroupBox { - border: 1px solid #45475a; + border: 1px solid #51576d; border-radius: 6px; margin-top: 1em; - color: #a6adc8; + color: #a5adce; font-weight: 600; } @@ -471,72 +471,72 @@ QGroupBox::title { /* ── Progress bar ────────────────────────────────────────────────────────── */ QProgressBar { - background-color: #313244; - border: 1px solid #45475a; + background-color: #414559; + border: 1px solid #51576d; border-radius: 6px; height: 10px; text-align: center; } QProgressBar::chunk { - background-color: #89b4fa; + background-color: #8caaee; border-radius: 5px; } /* ── Dock widget ─────────────────────────────────────────────────────────── */ QDockWidget { - color: #cdd6f4; + color: #c6d0f5; titlebar-close-icon: none; font-weight: 600; } QDockWidget::title { - background-color: #181825; + background-color: #292c3c; padding: 6px; - border-bottom: 1px solid #313244; + border-bottom: 1px solid #414559; } /* ── Tool button ─────────────────────────────────────────────────────────── */ QToolButton { - background-color: #313244; - color: #cdd6f4; - border: 1px solid #45475a; + background-color: #414559; + color: #c6d0f5; + border: 1px solid #51576d; border-radius: 5px; padding: 4px 8px; font-size: 13pt; } QToolButton:hover { - background-color: #45475a; + background-color: #51576d; } /* ── Message box ─────────────────────────────────────────────────────────── */ QMessageBox { - background-color: #1e1e2e; + background-color: #303446; } QMessageBox QLabel { - color: #cdd6f4; + color: #c6d0f5; font-size: 10pt; } /* ── Empty workspace label ───────────────────────────────────────────────── */ #emptyLabel { - color: #585b70; + color: #626880; font-size: 14pt; line-height: 2; } /* ── Status label in results toolbar ────────────────────────────────────── */ #statusLabel { - color: #a6adc8; + color: #a5adce; font-size: 9pt; padding-left: 4px; } /* ── DB label in SQL editor toolbar ─────────────────────────────────────── */ #dbLabel { - color: #6c7086; + color: #737994; font-size: 9pt; padding-right: 4px; } @@ -548,26 +548,26 @@ QMessageBox QLabel { /* ── Horizontal separator line in dialog ────────────────────────────────── */ QFrame[frameShape="4"] { /* HLine */ - color: #313244; + color: #414559; margin: 4px 0; } /* ── Structure view title ────────────────────────────────────────────────── */ #structureTitle { - color: #b4befe; + color: #babbf1; } /* ── Pagination bar ──────────────────────────────────────────────────────── */ #paginationBar { - background-color: #181825; - border-top: 1px solid #45475a; + background-color: #292c3c; + border-top: 1px solid #51576d; min-height: 38px; } #pgBtn { - background-color: #252536; - color: #cdd6f4; - border: 1px solid #45475a; + background-color: #363849; + color: #c6d0f5; + border: 1px solid #51576d; border-radius: 5px; padding: 4px 10px; font-size: 9pt; @@ -575,25 +575,25 @@ QFrame[frameShape="4"] { /* HLine */ } #pgBtn:hover { - background-color: #313244; - border-color: #585b70; + background-color: #414559; + border-color: #626880; } #pgBtn:disabled { - color: #45475a; - background-color: #1e1e2e; - border-color: #313244; + color: #51576d; + background-color: #303446; + border-color: #414559; } #pageLbl { - color: #89b4fa; + color: #8caaee; font-size: 9pt; font-weight: 600; padding: 0 6px; } #rowCountLbl { - color: #a6adc8; + color: #a5adce; font-size: 9pt; padding-left: 8px; }