theme: upgrade palette from Catppuccin Mocha to Frappé

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 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 16:51:37 -04:00
co-authored by Claude Sonnet 4.6
parent 22f1dd5f45
commit b003976d39
14 changed files with 221 additions and 221 deletions
+2 -2
View File
@@ -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", ""),
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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):
+11 -11
View File
@@ -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)
+9 -9
View File
@@ -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:
+1 -1
View File
@@ -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):
+4 -4
View File
@@ -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 ──────────────────────────────────────────────────────────
+6 -6
View File
@@ -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)
+4 -4
View File
@@ -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 ""
)
+11 -11
View File
@@ -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),
+2 -2
View File
@@ -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):
+6 -6
View File
@@ -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")
+1 -1
View File
@@ -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)
+161 -161
View File
@@ -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;
}