diff --git a/themes/README.md b/themes/README.md
index 3a93f2d..1a24125 100644
--- a/themes/README.md
+++ b/themes/README.md
@@ -66,14 +66,21 @@ slots that the body actually uses need to be defined.
## Included Themes
-| Theme | File | Preview |
-|-------|------|---------|
-| Nord | [nord.qss](nord.qss) |
|
-| Catppuccin Mocha | [catppuccin-mocha.qss](catppuccin-mocha.qss) |
|
-| Gruvbox | [gruvbox.qss](gruvbox.qss) |
|
-| Solarized Dark | [solarized-dark.qss](solarized-dark.qss) |
|
-| Tokyo Night | [tokyo-night.qss](tokyo-night.qss) |
|
-| Everforest | [everforest.qss](everforest.qss) |
|
+Each theme ships in two corner-radius variants:
+
+- **`*-rounded.qss`** — 4px radius on buttons, inputs, dropdowns, scrollbar handles, group boxes, tabs etc. The "default" Fusion-style look.
+- **`*-square.qss`** — every `border-radius:` declaration stripped *except* the one on `QRadioButton::indicator`, so radio buttons stay circular while everything else (buttons, inputs, scrollbars, tabs, group boxes, tooltips, progress bars, checkbox indicators) renders square.
+
+Pick whichever matches your overall desktop aesthetic. Both variants share the same `@palette` block, so you can swap one for the other and your colors carry over.
+
+| Theme | Rounded | Square |
+|-------|---------|--------|
+| Nord | [nord-rounded.qss](nord-rounded.qss) | [nord-square.qss](nord-square.qss) |
+| Catppuccin Mocha | [catppuccin-mocha-rounded.qss](catppuccin-mocha-rounded.qss) | [catppuccin-mocha-square.qss](catppuccin-mocha-square.qss) |
+| Gruvbox | [gruvbox-rounded.qss](gruvbox-rounded.qss) | [gruvbox-square.qss](gruvbox-square.qss) |
+| Solarized Dark | [solarized-dark-rounded.qss](solarized-dark-rounded.qss) | [solarized-dark-square.qss](solarized-dark-square.qss) |
+| Tokyo Night | [tokyo-night-rounded.qss](tokyo-night-rounded.qss) | [tokyo-night-square.qss](tokyo-night-square.qss) |
+| Everforest | [everforest-rounded.qss](everforest-rounded.qss) | [everforest-square.qss](everforest-square.qss) |
## Widget Targets
@@ -347,15 +354,21 @@ QRubberBand {
}
```
-### Thumbnail Indicators
+### Thumbnail Indicators and Selection Colors
```css
ThumbnailWidget {
- qproperty-savedColor: #22cc22; /* green dot: saved to library */
- qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-savedColor: #22cc22; /* green dot: saved to library */
+ qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: #cba6f7; /* selected cell border (3px) */
+ qproperty-multiSelectColor: #b4befe; /* multi-select fill + border */
+ qproperty-hoverColor: #cba6f7; /* hover border (1px) */
+ qproperty-idleColor: #45475a; /* idle 1px border */
}
```
+All four selection colors default to your system palette (`Highlight` + a derived idle color from `Mid`) so a `custom.qss` without these qproperties still picks up the theme. Override any of them to retint individual cell states without touching the global palette.
+
### Info Panel Tag Categories
The tag list in the info panel groups tags by category and colors each
diff --git a/themes/catppuccin-mocha.qss b/themes/catppuccin-mocha-rounded.qss
similarity index 98%
rename from themes/catppuccin-mocha.qss
rename to themes/catppuccin-mocha-rounded.qss
index 77ddcac..72fbba9 100644
--- a/themes/catppuccin-mocha.qss
+++ b/themes/catppuccin-mocha-rounded.qss
@@ -1,6 +1,6 @@
/* booru-viewer — Catppuccin Mocha
*
- * Edit the @palette block below to recolor this theme. The body uses
+ * Edit the @palette block below to recolor this rounded variant. The body uses
* ${...} placeholders that the app's _load_user_qss preprocessor
* substitutes at load time. See themes/README.md for the full list of
* placeholder names and what each one is used for.
@@ -515,6 +515,10 @@ QRubberBand {
ThumbnailWidget {
qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
}
/* ---------- Info panel tag category colors ---------- */
diff --git a/themes/catppuccin-mocha-square.qss b/themes/catppuccin-mocha-square.qss
new file mode 100644
index 0000000..054e00e
--- /dev/null
+++ b/themes/catppuccin-mocha-square.qss
@@ -0,0 +1,588 @@
+/* booru-viewer — Catppuccin Mocha
+ *
+ * Edit the @palette block below to recolor this square variant. The body uses
+ * ${...} placeholders that the app's _load_user_qss preprocessor
+ * substitutes at load time. See themes/README.md for the full list of
+ * placeholder names and what each one is used for.
+ *
+ * The same dialect works in any custom.qss you put in your data dir.
+ */
+
+/* @palette
+ bg: #1e1e2e
+ bg_alt: #181825
+ bg_subtle: #313244
+ bg_hover: #45475a
+ bg_active: #585b70
+ text: #cdd6f4
+ text_dim: #a6adc8
+ text_disabled: #6c7086
+ border: #313244
+ border_strong: #45475a
+ accent: #cba6f7
+ accent_text: #1e1e2e
+ accent_dim: #b4befe
+ link: #89b4fa
+ danger: #f38ba8
+ success: #a6e3a1
+ warning: #f9e2af
+ overlay_bg: rgba(30, 30, 46, 200)
+*/
+
+/* ---------- Base ---------- */
+
+QWidget {
+ background-color: ${bg};
+ color: ${text};
+ font-size: 13px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+
+QWidget:disabled {
+ color: ${text_disabled};
+}
+
+/* Labels should never paint an opaque background — they sit on top of
+ * other widgets in many places (toolbars, info panels, overlays). */
+QLabel {
+ background: transparent;
+}
+
+QMainWindow, QDialog {
+ background-color: ${bg};
+}
+
+/* ---------- Buttons ---------- */
+
+QPushButton {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 5px 12px;
+ min-height: 18px;
+}
+QPushButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${accent};
+}
+QPushButton:pressed {
+ background-color: ${bg_active};
+}
+QPushButton:checked {
+ background-color: ${accent};
+ color: ${accent_text};
+ border-color: ${accent};
+}
+QPushButton:checked:hover {
+ background-color: ${accent_dim};
+ border-color: ${accent_dim};
+}
+QPushButton:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+QPushButton:flat {
+ background: transparent;
+ border: none;
+}
+QPushButton:flat:hover {
+ background-color: ${bg_hover};
+}
+
+QToolButton {
+ background-color: transparent;
+ color: ${text};
+ border: 1px solid transparent;
+ padding: 4px;
+}
+QToolButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${border_strong};
+}
+QToolButton:pressed, QToolButton:checked {
+ background-color: ${bg_active};
+}
+
+/* ---------- Inputs ---------- */
+
+QLineEdit, QSpinBox, QDoubleSpinBox, QTextEdit, QPlainTextEdit {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ /* min-height ensures the painted text fits inside the widget bounds
+ * even when a parent layout (e.g. QFormLayout inside a QGroupBox)
+ * compresses the natural sizeHint. Without this, spinboxes in dense
+ * forms render with the top of the value text clipped. */
+ min-height: 20px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+QLineEdit:focus,
+QSpinBox:focus,
+QDoubleSpinBox:focus,
+QTextEdit:focus,
+QPlainTextEdit:focus {
+ border-color: ${accent};
+}
+QLineEdit:disabled,
+QSpinBox:disabled,
+QDoubleSpinBox:disabled,
+QTextEdit:disabled,
+QPlainTextEdit:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+
+QComboBox {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ min-height: 20px;
+}
+QComboBox:hover {
+ border-color: ${accent};
+}
+QComboBox:focus {
+ border-color: ${accent};
+}
+QComboBox::drop-down {
+ border: none;
+ width: 18px;
+}
+QComboBox QAbstractItemView {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+ padding: 2px;
+}
+
+/* ---------- Scrollbars ---------- */
+
+QScrollBar:vertical {
+ background: ${bg};
+ width: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:vertical {
+ background: ${bg_hover};
+ min-height: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:vertical:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:vertical,
+QScrollBar::sub-line:vertical {
+ height: 0;
+ border: none;
+}
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical {
+ background: transparent;
+}
+
+QScrollBar:horizontal {
+ background: ${bg};
+ height: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:horizontal {
+ background: ${bg_hover};
+ min-width: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:horizontal:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:horizontal,
+QScrollBar::sub-line:horizontal {
+ width: 0;
+ border: none;
+}
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
+ background: transparent;
+}
+
+QScrollArea {
+ background: transparent;
+ border: none;
+}
+
+/* ---------- Menus ---------- */
+
+QMenuBar {
+ background-color: ${bg};
+ color: ${text};
+ border-bottom: 1px solid ${border};
+}
+QMenuBar::item {
+ background: transparent;
+ padding: 4px 10px;
+}
+QMenuBar::item:selected {
+ background-color: ${bg_hover};
+ color: ${text};
+}
+QMenuBar::item:pressed {
+ background-color: ${bg_active};
+}
+
+QMenu {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 0;
+}
+QMenu::item {
+ background: transparent;
+ padding: 5px 24px 5px 24px;
+}
+QMenu::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+QMenu::item:disabled {
+ color: ${text_disabled};
+}
+QMenu::separator {
+ height: 1px;
+ background: ${border};
+ margin: 4px 8px;
+}
+QMenu::icon {
+ padding-left: 6px;
+}
+
+/* ---------- Status bar ---------- */
+
+QStatusBar {
+ background-color: ${bg};
+ color: ${text_dim};
+ border-top: 1px solid ${border};
+}
+QStatusBar::item {
+ border: none;
+}
+
+/* ---------- Splitters ---------- */
+
+QSplitter::handle {
+ background: ${border};
+}
+QSplitter::handle:horizontal {
+ width: 2px;
+}
+QSplitter::handle:vertical {
+ height: 2px;
+}
+QSplitter::handle:hover {
+ background: ${accent};
+}
+
+/* ---------- Sliders ---------- */
+
+QSlider::groove:horizontal {
+ background: ${bg_subtle};
+ height: 4px;
+}
+QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+QSlider::handle:horizontal {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: -5px 0;
+}
+QSlider::handle:horizontal:hover {
+ background: ${accent_dim};
+}
+
+QSlider::groove:vertical {
+ background: ${bg_subtle};
+ width: 4px;
+}
+QSlider::handle:vertical {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: 0 -5px;
+}
+
+/* ---------- Progress ---------- */
+
+QProgressBar {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border};
+ text-align: center;
+ height: 6px;
+}
+QProgressBar::chunk {
+ background-color: ${accent};
+}
+
+/* ---------- Checkboxes & radio buttons ---------- */
+
+QCheckBox, QRadioButton {
+ background: transparent;
+ color: ${text};
+ spacing: 6px;
+}
+QCheckBox::indicator, QRadioButton::indicator {
+ width: 14px;
+ height: 14px;
+ background-color: ${bg_subtle};
+ border: 1px solid ${border_strong};
+}
+QCheckBox::indicator {
+}
+QRadioButton::indicator {
+ border-radius: 7px;
+}
+QCheckBox::indicator:hover, QRadioButton::indicator:hover {
+ border-color: ${accent};
+}
+QCheckBox::indicator:checked, QRadioButton::indicator:checked {
+ background-color: ${accent};
+ border-color: ${accent};
+}
+QCheckBox::indicator:disabled, QRadioButton::indicator:disabled {
+ background-color: ${bg_alt};
+ border-color: ${border};
+}
+
+/* ---------- Tooltips ---------- */
+
+QToolTip {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 6px;
+}
+
+/* ---------- Item views (lists, trees, tables) ---------- */
+
+QListView, QListWidget, QTreeView, QTreeWidget, QTableView, QTableWidget {
+ background-color: ${bg};
+ alternate-background-color: ${bg_alt};
+ color: ${text};
+ border: 1px solid ${border};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+}
+QListView::item, QListWidget::item,
+QTreeView::item, QTreeWidget::item,
+QTableView::item, QTableWidget::item {
+ padding: 4px;
+}
+QListView::item:hover, QListWidget::item:hover,
+QTreeView::item:hover, QTreeWidget::item:hover,
+QTableView::item:hover, QTableWidget::item:hover {
+ background-color: ${bg_hover};
+}
+QListView::item:selected, QListWidget::item:selected,
+QTreeView::item:selected, QTreeWidget::item:selected,
+QTableView::item:selected, QTableWidget::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+
+QHeaderView::section {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: none;
+ border-right: 1px solid ${border};
+ padding: 4px 8px;
+}
+QHeaderView::section:hover {
+ background-color: ${bg_hover};
+}
+
+/* ---------- Tabs ---------- */
+
+QTabWidget::pane {
+ border: 1px solid ${border};
+ top: -1px;
+}
+QTabBar::tab {
+ background: ${bg_subtle};
+ color: ${text_dim};
+ border: 1px solid ${border};
+ border-bottom: none;
+ padding: 6px 14px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+QTabBar::tab:selected {
+ background: ${bg};
+ color: ${text};
+ border-color: ${border_strong};
+}
+QTabBar::tab:hover:!selected {
+ background: ${bg_hover};
+ color: ${text};
+}
+
+/* ---------- Group boxes ---------- */
+
+QGroupBox {
+ background: transparent;
+ color: ${text};
+ border: 1px solid ${border};
+ margin-top: 10px;
+ padding-top: 8px;
+}
+QGroupBox::title {
+ subcontrol-origin: margin;
+ subcontrol-position: top left;
+ padding: 0 6px;
+ color: ${text_dim};
+}
+
+/* ---------- Frames ---------- */
+
+QFrame[frameShape="4"], /* HLine */
+QFrame[frameShape="5"] /* VLine */ {
+ background: ${border};
+ color: ${border};
+}
+
+/* ---------- Toolbars ---------- */
+
+QToolBar {
+ background: ${bg};
+ border: none;
+ spacing: 4px;
+ padding: 2px;
+}
+QToolBar::separator {
+ background: ${border};
+ width: 1px;
+ margin: 4px 4px;
+}
+
+/* ---------- Dock widgets ---------- */
+
+QDockWidget {
+ color: ${text};
+ titlebar-close-icon: none;
+}
+QDockWidget::title {
+ background: ${bg_subtle};
+ padding: 4px;
+ border: 1px solid ${border};
+}
+
+/* ---------- Rubber band (multi-select drag rectangle) ---------- */
+
+QRubberBand {
+ background: ${accent};
+ border: 1px solid ${accent};
+ /* Qt blends rubber band at ~30% so this reads as a translucent
+ * accent-tinted rectangle without needing rgba(). */
+}
+
+
+
+/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
+
+ThumbnailWidget {
+ qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
+ qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
+}
+
+/* ---------- Info panel tag category colors ---------- */
+
+InfoPanel {
+ qproperty-tagArtistColor: ${warning};
+ qproperty-tagCharacterColor: ${success};
+ qproperty-tagCopyrightColor: ${accent};
+ qproperty-tagSpeciesColor: ${danger};
+ qproperty-tagMetaColor: ${text_dim};
+ qproperty-tagLoreColor: ${text_dim};
+}
+
+/* ---------- Video player letterbox / pillarbox color (mpv background) ---------- */
+
+VideoPlayer {
+ qproperty-letterboxColor: ${bg};
+}
+
+/* ---------- Popout overlay bars (slideshow toolbar + slideshow controls + embedded preview controls) ---------- */
+/*
+ * The popout window's translucent toolbar (top) and transport controls
+ * (bottom) float over the video content. The bg color comes from the
+ * @palette overlay_bg slot. Children get the classic overlay treatment:
+ * transparent backgrounds, near-white text, hairline borders.
+ */
+
+QWidget#_slideshow_toolbar,
+QWidget#_slideshow_controls,
+QWidget#_preview_controls {
+ background: ${overlay_bg};
+}
+
+QWidget#_slideshow_toolbar *,
+QWidget#_slideshow_controls *,
+QWidget#_preview_controls * {
+ background: transparent;
+ color: white;
+ border: none;
+}
+
+QWidget#_slideshow_toolbar QPushButton,
+QWidget#_slideshow_controls QPushButton,
+QWidget#_preview_controls QPushButton {
+ background: transparent;
+ color: white;
+ border: 1px solid rgba(255, 255, 255, 80);
+ padding: 2px 6px;
+}
+QWidget#_slideshow_toolbar QPushButton:hover,
+QWidget#_slideshow_controls QPushButton:hover,
+QWidget#_preview_controls QPushButton:hover {
+ background: rgba(255, 255, 255, 30);
+}
+
+QWidget#_slideshow_toolbar QSlider::groove:horizontal,
+QWidget#_slideshow_controls QSlider::groove:horizontal,
+QWidget#_preview_controls QSlider::groove:horizontal {
+ background: rgba(255, 255, 255, 40);
+ height: 4px;
+}
+QWidget#_slideshow_toolbar QSlider::handle:horizontal,
+QWidget#_slideshow_controls QSlider::handle:horizontal,
+QWidget#_preview_controls QSlider::handle:horizontal {
+ background: ${accent};
+ width: 10px;
+ margin: -4px 0;
+}
+QWidget#_slideshow_toolbar QSlider::sub-page:horizontal,
+QWidget#_slideshow_controls QSlider::sub-page:horizontal,
+QWidget#_preview_controls QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+
+QWidget#_slideshow_toolbar QLabel,
+QWidget#_slideshow_controls QLabel,
+QWidget#_preview_controls QLabel {
+ background: transparent;
+ color: white;
+}
diff --git a/themes/everforest.qss b/themes/everforest-rounded.qss
similarity index 98%
rename from themes/everforest.qss
rename to themes/everforest-rounded.qss
index bd17985..3a7215b 100644
--- a/themes/everforest.qss
+++ b/themes/everforest-rounded.qss
@@ -1,6 +1,6 @@
/* booru-viewer — Everforest Dark
*
- * Edit the @palette block below to recolor this theme. The body uses
+ * Edit the @palette block below to recolor this rounded variant. The body uses
* ${...} placeholders that the app's _load_user_qss preprocessor
* substitutes at load time. See themes/README.md for the full list of
* placeholder names and what each one is used for.
@@ -515,6 +515,10 @@ QRubberBand {
ThumbnailWidget {
qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
}
/* ---------- Info panel tag category colors ---------- */
diff --git a/themes/everforest-square.qss b/themes/everforest-square.qss
new file mode 100644
index 0000000..e59289c
--- /dev/null
+++ b/themes/everforest-square.qss
@@ -0,0 +1,588 @@
+/* booru-viewer — Everforest Dark
+ *
+ * Edit the @palette block below to recolor this square variant. The body uses
+ * ${...} placeholders that the app's _load_user_qss preprocessor
+ * substitutes at load time. See themes/README.md for the full list of
+ * placeholder names and what each one is used for.
+ *
+ * The same dialect works in any custom.qss you put in your data dir.
+ */
+
+/* @palette
+ bg: #2d353b
+ bg_alt: #232a2e
+ bg_subtle: #343f44
+ bg_hover: #3d484d
+ bg_active: #4f585e
+ text: #d3c6aa
+ text_dim: #9da9a0
+ text_disabled: #7a8478
+ border: #343f44
+ border_strong: #3d484d
+ accent: #a7c080
+ accent_text: #2d353b
+ accent_dim: #83c092
+ link: #7fbbb3
+ danger: #e67e80
+ success: #a7c080
+ warning: #dbbc7f
+ overlay_bg: rgba(45, 53, 59, 200)
+*/
+
+/* ---------- Base ---------- */
+
+QWidget {
+ background-color: ${bg};
+ color: ${text};
+ font-size: 13px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+
+QWidget:disabled {
+ color: ${text_disabled};
+}
+
+/* Labels should never paint an opaque background — they sit on top of
+ * other widgets in many places (toolbars, info panels, overlays). */
+QLabel {
+ background: transparent;
+}
+
+QMainWindow, QDialog {
+ background-color: ${bg};
+}
+
+/* ---------- Buttons ---------- */
+
+QPushButton {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 5px 12px;
+ min-height: 18px;
+}
+QPushButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${accent};
+}
+QPushButton:pressed {
+ background-color: ${bg_active};
+}
+QPushButton:checked {
+ background-color: ${accent};
+ color: ${accent_text};
+ border-color: ${accent};
+}
+QPushButton:checked:hover {
+ background-color: ${accent_dim};
+ border-color: ${accent_dim};
+}
+QPushButton:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+QPushButton:flat {
+ background: transparent;
+ border: none;
+}
+QPushButton:flat:hover {
+ background-color: ${bg_hover};
+}
+
+QToolButton {
+ background-color: transparent;
+ color: ${text};
+ border: 1px solid transparent;
+ padding: 4px;
+}
+QToolButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${border_strong};
+}
+QToolButton:pressed, QToolButton:checked {
+ background-color: ${bg_active};
+}
+
+/* ---------- Inputs ---------- */
+
+QLineEdit, QSpinBox, QDoubleSpinBox, QTextEdit, QPlainTextEdit {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ /* min-height ensures the painted text fits inside the widget bounds
+ * even when a parent layout (e.g. QFormLayout inside a QGroupBox)
+ * compresses the natural sizeHint. Without this, spinboxes in dense
+ * forms render with the top of the value text clipped. */
+ min-height: 20px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+QLineEdit:focus,
+QSpinBox:focus,
+QDoubleSpinBox:focus,
+QTextEdit:focus,
+QPlainTextEdit:focus {
+ border-color: ${accent};
+}
+QLineEdit:disabled,
+QSpinBox:disabled,
+QDoubleSpinBox:disabled,
+QTextEdit:disabled,
+QPlainTextEdit:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+
+QComboBox {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ min-height: 20px;
+}
+QComboBox:hover {
+ border-color: ${accent};
+}
+QComboBox:focus {
+ border-color: ${accent};
+}
+QComboBox::drop-down {
+ border: none;
+ width: 18px;
+}
+QComboBox QAbstractItemView {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+ padding: 2px;
+}
+
+/* ---------- Scrollbars ---------- */
+
+QScrollBar:vertical {
+ background: ${bg};
+ width: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:vertical {
+ background: ${bg_hover};
+ min-height: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:vertical:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:vertical,
+QScrollBar::sub-line:vertical {
+ height: 0;
+ border: none;
+}
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical {
+ background: transparent;
+}
+
+QScrollBar:horizontal {
+ background: ${bg};
+ height: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:horizontal {
+ background: ${bg_hover};
+ min-width: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:horizontal:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:horizontal,
+QScrollBar::sub-line:horizontal {
+ width: 0;
+ border: none;
+}
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
+ background: transparent;
+}
+
+QScrollArea {
+ background: transparent;
+ border: none;
+}
+
+/* ---------- Menus ---------- */
+
+QMenuBar {
+ background-color: ${bg};
+ color: ${text};
+ border-bottom: 1px solid ${border};
+}
+QMenuBar::item {
+ background: transparent;
+ padding: 4px 10px;
+}
+QMenuBar::item:selected {
+ background-color: ${bg_hover};
+ color: ${text};
+}
+QMenuBar::item:pressed {
+ background-color: ${bg_active};
+}
+
+QMenu {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 0;
+}
+QMenu::item {
+ background: transparent;
+ padding: 5px 24px 5px 24px;
+}
+QMenu::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+QMenu::item:disabled {
+ color: ${text_disabled};
+}
+QMenu::separator {
+ height: 1px;
+ background: ${border};
+ margin: 4px 8px;
+}
+QMenu::icon {
+ padding-left: 6px;
+}
+
+/* ---------- Status bar ---------- */
+
+QStatusBar {
+ background-color: ${bg};
+ color: ${text_dim};
+ border-top: 1px solid ${border};
+}
+QStatusBar::item {
+ border: none;
+}
+
+/* ---------- Splitters ---------- */
+
+QSplitter::handle {
+ background: ${border};
+}
+QSplitter::handle:horizontal {
+ width: 2px;
+}
+QSplitter::handle:vertical {
+ height: 2px;
+}
+QSplitter::handle:hover {
+ background: ${accent};
+}
+
+/* ---------- Sliders ---------- */
+
+QSlider::groove:horizontal {
+ background: ${bg_subtle};
+ height: 4px;
+}
+QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+QSlider::handle:horizontal {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: -5px 0;
+}
+QSlider::handle:horizontal:hover {
+ background: ${accent_dim};
+}
+
+QSlider::groove:vertical {
+ background: ${bg_subtle};
+ width: 4px;
+}
+QSlider::handle:vertical {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: 0 -5px;
+}
+
+/* ---------- Progress ---------- */
+
+QProgressBar {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border};
+ text-align: center;
+ height: 6px;
+}
+QProgressBar::chunk {
+ background-color: ${accent};
+}
+
+/* ---------- Checkboxes & radio buttons ---------- */
+
+QCheckBox, QRadioButton {
+ background: transparent;
+ color: ${text};
+ spacing: 6px;
+}
+QCheckBox::indicator, QRadioButton::indicator {
+ width: 14px;
+ height: 14px;
+ background-color: ${bg_subtle};
+ border: 1px solid ${border_strong};
+}
+QCheckBox::indicator {
+}
+QRadioButton::indicator {
+ border-radius: 7px;
+}
+QCheckBox::indicator:hover, QRadioButton::indicator:hover {
+ border-color: ${accent};
+}
+QCheckBox::indicator:checked, QRadioButton::indicator:checked {
+ background-color: ${accent};
+ border-color: ${accent};
+}
+QCheckBox::indicator:disabled, QRadioButton::indicator:disabled {
+ background-color: ${bg_alt};
+ border-color: ${border};
+}
+
+/* ---------- Tooltips ---------- */
+
+QToolTip {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 6px;
+}
+
+/* ---------- Item views (lists, trees, tables) ---------- */
+
+QListView, QListWidget, QTreeView, QTreeWidget, QTableView, QTableWidget {
+ background-color: ${bg};
+ alternate-background-color: ${bg_alt};
+ color: ${text};
+ border: 1px solid ${border};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+}
+QListView::item, QListWidget::item,
+QTreeView::item, QTreeWidget::item,
+QTableView::item, QTableWidget::item {
+ padding: 4px;
+}
+QListView::item:hover, QListWidget::item:hover,
+QTreeView::item:hover, QTreeWidget::item:hover,
+QTableView::item:hover, QTableWidget::item:hover {
+ background-color: ${bg_hover};
+}
+QListView::item:selected, QListWidget::item:selected,
+QTreeView::item:selected, QTreeWidget::item:selected,
+QTableView::item:selected, QTableWidget::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+
+QHeaderView::section {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: none;
+ border-right: 1px solid ${border};
+ padding: 4px 8px;
+}
+QHeaderView::section:hover {
+ background-color: ${bg_hover};
+}
+
+/* ---------- Tabs ---------- */
+
+QTabWidget::pane {
+ border: 1px solid ${border};
+ top: -1px;
+}
+QTabBar::tab {
+ background: ${bg_subtle};
+ color: ${text_dim};
+ border: 1px solid ${border};
+ border-bottom: none;
+ padding: 6px 14px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+QTabBar::tab:selected {
+ background: ${bg};
+ color: ${text};
+ border-color: ${border_strong};
+}
+QTabBar::tab:hover:!selected {
+ background: ${bg_hover};
+ color: ${text};
+}
+
+/* ---------- Group boxes ---------- */
+
+QGroupBox {
+ background: transparent;
+ color: ${text};
+ border: 1px solid ${border};
+ margin-top: 10px;
+ padding-top: 8px;
+}
+QGroupBox::title {
+ subcontrol-origin: margin;
+ subcontrol-position: top left;
+ padding: 0 6px;
+ color: ${text_dim};
+}
+
+/* ---------- Frames ---------- */
+
+QFrame[frameShape="4"], /* HLine */
+QFrame[frameShape="5"] /* VLine */ {
+ background: ${border};
+ color: ${border};
+}
+
+/* ---------- Toolbars ---------- */
+
+QToolBar {
+ background: ${bg};
+ border: none;
+ spacing: 4px;
+ padding: 2px;
+}
+QToolBar::separator {
+ background: ${border};
+ width: 1px;
+ margin: 4px 4px;
+}
+
+/* ---------- Dock widgets ---------- */
+
+QDockWidget {
+ color: ${text};
+ titlebar-close-icon: none;
+}
+QDockWidget::title {
+ background: ${bg_subtle};
+ padding: 4px;
+ border: 1px solid ${border};
+}
+
+/* ---------- Rubber band (multi-select drag rectangle) ---------- */
+
+QRubberBand {
+ background: ${accent};
+ border: 1px solid ${accent};
+ /* Qt blends rubber band at ~30% so this reads as a translucent
+ * accent-tinted rectangle without needing rgba(). */
+}
+
+
+
+/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
+
+ThumbnailWidget {
+ qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
+ qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
+}
+
+/* ---------- Info panel tag category colors ---------- */
+
+InfoPanel {
+ qproperty-tagArtistColor: ${warning};
+ qproperty-tagCharacterColor: ${success};
+ qproperty-tagCopyrightColor: ${accent};
+ qproperty-tagSpeciesColor: ${danger};
+ qproperty-tagMetaColor: ${text_dim};
+ qproperty-tagLoreColor: ${text_dim};
+}
+
+/* ---------- Video player letterbox / pillarbox color (mpv background) ---------- */
+
+VideoPlayer {
+ qproperty-letterboxColor: ${bg};
+}
+
+/* ---------- Popout overlay bars (slideshow toolbar + slideshow controls + embedded preview controls) ---------- */
+/*
+ * The popout window's translucent toolbar (top) and transport controls
+ * (bottom) float over the video content. The bg color comes from the
+ * @palette overlay_bg slot. Children get the classic overlay treatment:
+ * transparent backgrounds, near-white text, hairline borders.
+ */
+
+QWidget#_slideshow_toolbar,
+QWidget#_slideshow_controls,
+QWidget#_preview_controls {
+ background: ${overlay_bg};
+}
+
+QWidget#_slideshow_toolbar *,
+QWidget#_slideshow_controls *,
+QWidget#_preview_controls * {
+ background: transparent;
+ color: white;
+ border: none;
+}
+
+QWidget#_slideshow_toolbar QPushButton,
+QWidget#_slideshow_controls QPushButton,
+QWidget#_preview_controls QPushButton {
+ background: transparent;
+ color: white;
+ border: 1px solid rgba(255, 255, 255, 80);
+ padding: 2px 6px;
+}
+QWidget#_slideshow_toolbar QPushButton:hover,
+QWidget#_slideshow_controls QPushButton:hover,
+QWidget#_preview_controls QPushButton:hover {
+ background: rgba(255, 255, 255, 30);
+}
+
+QWidget#_slideshow_toolbar QSlider::groove:horizontal,
+QWidget#_slideshow_controls QSlider::groove:horizontal,
+QWidget#_preview_controls QSlider::groove:horizontal {
+ background: rgba(255, 255, 255, 40);
+ height: 4px;
+}
+QWidget#_slideshow_toolbar QSlider::handle:horizontal,
+QWidget#_slideshow_controls QSlider::handle:horizontal,
+QWidget#_preview_controls QSlider::handle:horizontal {
+ background: ${accent};
+ width: 10px;
+ margin: -4px 0;
+}
+QWidget#_slideshow_toolbar QSlider::sub-page:horizontal,
+QWidget#_slideshow_controls QSlider::sub-page:horizontal,
+QWidget#_preview_controls QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+
+QWidget#_slideshow_toolbar QLabel,
+QWidget#_slideshow_controls QLabel,
+QWidget#_preview_controls QLabel {
+ background: transparent;
+ color: white;
+}
diff --git a/themes/gruvbox.qss b/themes/gruvbox-rounded.qss
similarity index 98%
rename from themes/gruvbox.qss
rename to themes/gruvbox-rounded.qss
index cbda47a..be578d6 100644
--- a/themes/gruvbox.qss
+++ b/themes/gruvbox-rounded.qss
@@ -1,6 +1,6 @@
/* booru-viewer — Gruvbox Dark
*
- * Edit the @palette block below to recolor this theme. The body uses
+ * Edit the @palette block below to recolor this rounded variant. The body uses
* ${...} placeholders that the app's _load_user_qss preprocessor
* substitutes at load time. See themes/README.md for the full list of
* placeholder names and what each one is used for.
@@ -515,6 +515,10 @@ QRubberBand {
ThumbnailWidget {
qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
}
/* ---------- Info panel tag category colors ---------- */
diff --git a/themes/gruvbox-square.qss b/themes/gruvbox-square.qss
new file mode 100644
index 0000000..ce02e96
--- /dev/null
+++ b/themes/gruvbox-square.qss
@@ -0,0 +1,588 @@
+/* booru-viewer — Gruvbox Dark
+ *
+ * Edit the @palette block below to recolor this square variant. The body uses
+ * ${...} placeholders that the app's _load_user_qss preprocessor
+ * substitutes at load time. See themes/README.md for the full list of
+ * placeholder names and what each one is used for.
+ *
+ * The same dialect works in any custom.qss you put in your data dir.
+ */
+
+/* @palette
+ bg: #282828
+ bg_alt: #1d2021
+ bg_subtle: #3c3836
+ bg_hover: #504945
+ bg_active: #665c54
+ text: #ebdbb2
+ text_dim: #d5c4a1
+ text_disabled: #928374
+ border: #3c3836
+ border_strong: #504945
+ accent: #d79921
+ accent_text: #282828
+ accent_dim: #fabd2f
+ link: #83a598
+ danger: #fb4934
+ success: #b8bb26
+ warning: #fabd2f
+ overlay_bg: rgba(40, 40, 40, 200)
+*/
+
+/* ---------- Base ---------- */
+
+QWidget {
+ background-color: ${bg};
+ color: ${text};
+ font-size: 13px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+
+QWidget:disabled {
+ color: ${text_disabled};
+}
+
+/* Labels should never paint an opaque background — they sit on top of
+ * other widgets in many places (toolbars, info panels, overlays). */
+QLabel {
+ background: transparent;
+}
+
+QMainWindow, QDialog {
+ background-color: ${bg};
+}
+
+/* ---------- Buttons ---------- */
+
+QPushButton {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 5px 12px;
+ min-height: 18px;
+}
+QPushButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${accent};
+}
+QPushButton:pressed {
+ background-color: ${bg_active};
+}
+QPushButton:checked {
+ background-color: ${accent};
+ color: ${accent_text};
+ border-color: ${accent};
+}
+QPushButton:checked:hover {
+ background-color: ${accent_dim};
+ border-color: ${accent_dim};
+}
+QPushButton:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+QPushButton:flat {
+ background: transparent;
+ border: none;
+}
+QPushButton:flat:hover {
+ background-color: ${bg_hover};
+}
+
+QToolButton {
+ background-color: transparent;
+ color: ${text};
+ border: 1px solid transparent;
+ padding: 4px;
+}
+QToolButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${border_strong};
+}
+QToolButton:pressed, QToolButton:checked {
+ background-color: ${bg_active};
+}
+
+/* ---------- Inputs ---------- */
+
+QLineEdit, QSpinBox, QDoubleSpinBox, QTextEdit, QPlainTextEdit {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ /* min-height ensures the painted text fits inside the widget bounds
+ * even when a parent layout (e.g. QFormLayout inside a QGroupBox)
+ * compresses the natural sizeHint. Without this, spinboxes in dense
+ * forms render with the top of the value text clipped. */
+ min-height: 20px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+QLineEdit:focus,
+QSpinBox:focus,
+QDoubleSpinBox:focus,
+QTextEdit:focus,
+QPlainTextEdit:focus {
+ border-color: ${accent};
+}
+QLineEdit:disabled,
+QSpinBox:disabled,
+QDoubleSpinBox:disabled,
+QTextEdit:disabled,
+QPlainTextEdit:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+
+QComboBox {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ min-height: 20px;
+}
+QComboBox:hover {
+ border-color: ${accent};
+}
+QComboBox:focus {
+ border-color: ${accent};
+}
+QComboBox::drop-down {
+ border: none;
+ width: 18px;
+}
+QComboBox QAbstractItemView {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+ padding: 2px;
+}
+
+/* ---------- Scrollbars ---------- */
+
+QScrollBar:vertical {
+ background: ${bg};
+ width: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:vertical {
+ background: ${bg_hover};
+ min-height: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:vertical:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:vertical,
+QScrollBar::sub-line:vertical {
+ height: 0;
+ border: none;
+}
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical {
+ background: transparent;
+}
+
+QScrollBar:horizontal {
+ background: ${bg};
+ height: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:horizontal {
+ background: ${bg_hover};
+ min-width: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:horizontal:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:horizontal,
+QScrollBar::sub-line:horizontal {
+ width: 0;
+ border: none;
+}
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
+ background: transparent;
+}
+
+QScrollArea {
+ background: transparent;
+ border: none;
+}
+
+/* ---------- Menus ---------- */
+
+QMenuBar {
+ background-color: ${bg};
+ color: ${text};
+ border-bottom: 1px solid ${border};
+}
+QMenuBar::item {
+ background: transparent;
+ padding: 4px 10px;
+}
+QMenuBar::item:selected {
+ background-color: ${bg_hover};
+ color: ${text};
+}
+QMenuBar::item:pressed {
+ background-color: ${bg_active};
+}
+
+QMenu {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 0;
+}
+QMenu::item {
+ background: transparent;
+ padding: 5px 24px 5px 24px;
+}
+QMenu::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+QMenu::item:disabled {
+ color: ${text_disabled};
+}
+QMenu::separator {
+ height: 1px;
+ background: ${border};
+ margin: 4px 8px;
+}
+QMenu::icon {
+ padding-left: 6px;
+}
+
+/* ---------- Status bar ---------- */
+
+QStatusBar {
+ background-color: ${bg};
+ color: ${text_dim};
+ border-top: 1px solid ${border};
+}
+QStatusBar::item {
+ border: none;
+}
+
+/* ---------- Splitters ---------- */
+
+QSplitter::handle {
+ background: ${border};
+}
+QSplitter::handle:horizontal {
+ width: 2px;
+}
+QSplitter::handle:vertical {
+ height: 2px;
+}
+QSplitter::handle:hover {
+ background: ${accent};
+}
+
+/* ---------- Sliders ---------- */
+
+QSlider::groove:horizontal {
+ background: ${bg_subtle};
+ height: 4px;
+}
+QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+QSlider::handle:horizontal {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: -5px 0;
+}
+QSlider::handle:horizontal:hover {
+ background: ${accent_dim};
+}
+
+QSlider::groove:vertical {
+ background: ${bg_subtle};
+ width: 4px;
+}
+QSlider::handle:vertical {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: 0 -5px;
+}
+
+/* ---------- Progress ---------- */
+
+QProgressBar {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border};
+ text-align: center;
+ height: 6px;
+}
+QProgressBar::chunk {
+ background-color: ${accent};
+}
+
+/* ---------- Checkboxes & radio buttons ---------- */
+
+QCheckBox, QRadioButton {
+ background: transparent;
+ color: ${text};
+ spacing: 6px;
+}
+QCheckBox::indicator, QRadioButton::indicator {
+ width: 14px;
+ height: 14px;
+ background-color: ${bg_subtle};
+ border: 1px solid ${border_strong};
+}
+QCheckBox::indicator {
+}
+QRadioButton::indicator {
+ border-radius: 7px;
+}
+QCheckBox::indicator:hover, QRadioButton::indicator:hover {
+ border-color: ${accent};
+}
+QCheckBox::indicator:checked, QRadioButton::indicator:checked {
+ background-color: ${accent};
+ border-color: ${accent};
+}
+QCheckBox::indicator:disabled, QRadioButton::indicator:disabled {
+ background-color: ${bg_alt};
+ border-color: ${border};
+}
+
+/* ---------- Tooltips ---------- */
+
+QToolTip {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 6px;
+}
+
+/* ---------- Item views (lists, trees, tables) ---------- */
+
+QListView, QListWidget, QTreeView, QTreeWidget, QTableView, QTableWidget {
+ background-color: ${bg};
+ alternate-background-color: ${bg_alt};
+ color: ${text};
+ border: 1px solid ${border};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+}
+QListView::item, QListWidget::item,
+QTreeView::item, QTreeWidget::item,
+QTableView::item, QTableWidget::item {
+ padding: 4px;
+}
+QListView::item:hover, QListWidget::item:hover,
+QTreeView::item:hover, QTreeWidget::item:hover,
+QTableView::item:hover, QTableWidget::item:hover {
+ background-color: ${bg_hover};
+}
+QListView::item:selected, QListWidget::item:selected,
+QTreeView::item:selected, QTreeWidget::item:selected,
+QTableView::item:selected, QTableWidget::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+
+QHeaderView::section {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: none;
+ border-right: 1px solid ${border};
+ padding: 4px 8px;
+}
+QHeaderView::section:hover {
+ background-color: ${bg_hover};
+}
+
+/* ---------- Tabs ---------- */
+
+QTabWidget::pane {
+ border: 1px solid ${border};
+ top: -1px;
+}
+QTabBar::tab {
+ background: ${bg_subtle};
+ color: ${text_dim};
+ border: 1px solid ${border};
+ border-bottom: none;
+ padding: 6px 14px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+QTabBar::tab:selected {
+ background: ${bg};
+ color: ${text};
+ border-color: ${border_strong};
+}
+QTabBar::tab:hover:!selected {
+ background: ${bg_hover};
+ color: ${text};
+}
+
+/* ---------- Group boxes ---------- */
+
+QGroupBox {
+ background: transparent;
+ color: ${text};
+ border: 1px solid ${border};
+ margin-top: 10px;
+ padding-top: 8px;
+}
+QGroupBox::title {
+ subcontrol-origin: margin;
+ subcontrol-position: top left;
+ padding: 0 6px;
+ color: ${text_dim};
+}
+
+/* ---------- Frames ---------- */
+
+QFrame[frameShape="4"], /* HLine */
+QFrame[frameShape="5"] /* VLine */ {
+ background: ${border};
+ color: ${border};
+}
+
+/* ---------- Toolbars ---------- */
+
+QToolBar {
+ background: ${bg};
+ border: none;
+ spacing: 4px;
+ padding: 2px;
+}
+QToolBar::separator {
+ background: ${border};
+ width: 1px;
+ margin: 4px 4px;
+}
+
+/* ---------- Dock widgets ---------- */
+
+QDockWidget {
+ color: ${text};
+ titlebar-close-icon: none;
+}
+QDockWidget::title {
+ background: ${bg_subtle};
+ padding: 4px;
+ border: 1px solid ${border};
+}
+
+/* ---------- Rubber band (multi-select drag rectangle) ---------- */
+
+QRubberBand {
+ background: ${accent};
+ border: 1px solid ${accent};
+ /* Qt blends rubber band at ~30% so this reads as a translucent
+ * accent-tinted rectangle without needing rgba(). */
+}
+
+
+
+/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
+
+ThumbnailWidget {
+ qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
+ qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
+}
+
+/* ---------- Info panel tag category colors ---------- */
+
+InfoPanel {
+ qproperty-tagArtistColor: ${warning};
+ qproperty-tagCharacterColor: ${success};
+ qproperty-tagCopyrightColor: ${accent};
+ qproperty-tagSpeciesColor: ${danger};
+ qproperty-tagMetaColor: ${text_dim};
+ qproperty-tagLoreColor: ${text_dim};
+}
+
+/* ---------- Video player letterbox / pillarbox color (mpv background) ---------- */
+
+VideoPlayer {
+ qproperty-letterboxColor: ${bg};
+}
+
+/* ---------- Popout overlay bars (slideshow toolbar + slideshow controls + embedded preview controls) ---------- */
+/*
+ * The popout window's translucent toolbar (top) and transport controls
+ * (bottom) float over the video content. The bg color comes from the
+ * @palette overlay_bg slot. Children get the classic overlay treatment:
+ * transparent backgrounds, near-white text, hairline borders.
+ */
+
+QWidget#_slideshow_toolbar,
+QWidget#_slideshow_controls,
+QWidget#_preview_controls {
+ background: ${overlay_bg};
+}
+
+QWidget#_slideshow_toolbar *,
+QWidget#_slideshow_controls *,
+QWidget#_preview_controls * {
+ background: transparent;
+ color: white;
+ border: none;
+}
+
+QWidget#_slideshow_toolbar QPushButton,
+QWidget#_slideshow_controls QPushButton,
+QWidget#_preview_controls QPushButton {
+ background: transparent;
+ color: white;
+ border: 1px solid rgba(255, 255, 255, 80);
+ padding: 2px 6px;
+}
+QWidget#_slideshow_toolbar QPushButton:hover,
+QWidget#_slideshow_controls QPushButton:hover,
+QWidget#_preview_controls QPushButton:hover {
+ background: rgba(255, 255, 255, 30);
+}
+
+QWidget#_slideshow_toolbar QSlider::groove:horizontal,
+QWidget#_slideshow_controls QSlider::groove:horizontal,
+QWidget#_preview_controls QSlider::groove:horizontal {
+ background: rgba(255, 255, 255, 40);
+ height: 4px;
+}
+QWidget#_slideshow_toolbar QSlider::handle:horizontal,
+QWidget#_slideshow_controls QSlider::handle:horizontal,
+QWidget#_preview_controls QSlider::handle:horizontal {
+ background: ${accent};
+ width: 10px;
+ margin: -4px 0;
+}
+QWidget#_slideshow_toolbar QSlider::sub-page:horizontal,
+QWidget#_slideshow_controls QSlider::sub-page:horizontal,
+QWidget#_preview_controls QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+
+QWidget#_slideshow_toolbar QLabel,
+QWidget#_slideshow_controls QLabel,
+QWidget#_preview_controls QLabel {
+ background: transparent;
+ color: white;
+}
diff --git a/themes/nord.qss b/themes/nord-rounded.qss
similarity index 98%
rename from themes/nord.qss
rename to themes/nord-rounded.qss
index 7826993..5d0e7e5 100644
--- a/themes/nord.qss
+++ b/themes/nord-rounded.qss
@@ -1,6 +1,6 @@
/* booru-viewer — Nord
*
- * Edit the @palette block below to recolor this theme. The body uses
+ * Edit the @palette block below to recolor this rounded variant. The body uses
* ${...} placeholders that the app's _load_user_qss preprocessor
* substitutes at load time. See themes/README.md for the full list of
* placeholder names and what each one is used for.
@@ -515,6 +515,10 @@ QRubberBand {
ThumbnailWidget {
qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
}
/* ---------- Info panel tag category colors ---------- */
diff --git a/themes/nord-square.qss b/themes/nord-square.qss
new file mode 100644
index 0000000..dba2ad9
--- /dev/null
+++ b/themes/nord-square.qss
@@ -0,0 +1,588 @@
+/* booru-viewer — Nord
+ *
+ * Edit the @palette block below to recolor this square variant. The body uses
+ * ${...} placeholders that the app's _load_user_qss preprocessor
+ * substitutes at load time. See themes/README.md for the full list of
+ * placeholder names and what each one is used for.
+ *
+ * The same dialect works in any custom.qss you put in your data dir.
+ */
+
+/* @palette
+ bg: #2e3440
+ bg_alt: #272b36
+ bg_subtle: #3b4252
+ bg_hover: #434c5e
+ bg_active: #4c566a
+ text: #eceff4
+ text_dim: #d8dee9
+ text_disabled: #4c566a
+ border: #3b4252
+ border_strong: #4c566a
+ accent: #88c0d0
+ accent_text: #2e3440
+ accent_dim: #81a1c1
+ link: #8fbcbb
+ danger: #bf616a
+ success: #a3be8c
+ warning: #ebcb8b
+ overlay_bg: rgba(46, 52, 64, 200)
+*/
+
+/* ---------- Base ---------- */
+
+QWidget {
+ background-color: ${bg};
+ color: ${text};
+ font-size: 13px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+
+QWidget:disabled {
+ color: ${text_disabled};
+}
+
+/* Labels should never paint an opaque background — they sit on top of
+ * other widgets in many places (toolbars, info panels, overlays). */
+QLabel {
+ background: transparent;
+}
+
+QMainWindow, QDialog {
+ background-color: ${bg};
+}
+
+/* ---------- Buttons ---------- */
+
+QPushButton {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 5px 12px;
+ min-height: 18px;
+}
+QPushButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${accent};
+}
+QPushButton:pressed {
+ background-color: ${bg_active};
+}
+QPushButton:checked {
+ background-color: ${accent};
+ color: ${accent_text};
+ border-color: ${accent};
+}
+QPushButton:checked:hover {
+ background-color: ${accent_dim};
+ border-color: ${accent_dim};
+}
+QPushButton:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+QPushButton:flat {
+ background: transparent;
+ border: none;
+}
+QPushButton:flat:hover {
+ background-color: ${bg_hover};
+}
+
+QToolButton {
+ background-color: transparent;
+ color: ${text};
+ border: 1px solid transparent;
+ padding: 4px;
+}
+QToolButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${border_strong};
+}
+QToolButton:pressed, QToolButton:checked {
+ background-color: ${bg_active};
+}
+
+/* ---------- Inputs ---------- */
+
+QLineEdit, QSpinBox, QDoubleSpinBox, QTextEdit, QPlainTextEdit {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ /* min-height ensures the painted text fits inside the widget bounds
+ * even when a parent layout (e.g. QFormLayout inside a QGroupBox)
+ * compresses the natural sizeHint. Without this, spinboxes in dense
+ * forms render with the top of the value text clipped. */
+ min-height: 20px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+QLineEdit:focus,
+QSpinBox:focus,
+QDoubleSpinBox:focus,
+QTextEdit:focus,
+QPlainTextEdit:focus {
+ border-color: ${accent};
+}
+QLineEdit:disabled,
+QSpinBox:disabled,
+QDoubleSpinBox:disabled,
+QTextEdit:disabled,
+QPlainTextEdit:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+
+QComboBox {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ min-height: 20px;
+}
+QComboBox:hover {
+ border-color: ${accent};
+}
+QComboBox:focus {
+ border-color: ${accent};
+}
+QComboBox::drop-down {
+ border: none;
+ width: 18px;
+}
+QComboBox QAbstractItemView {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+ padding: 2px;
+}
+
+/* ---------- Scrollbars ---------- */
+
+QScrollBar:vertical {
+ background: ${bg};
+ width: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:vertical {
+ background: ${bg_hover};
+ min-height: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:vertical:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:vertical,
+QScrollBar::sub-line:vertical {
+ height: 0;
+ border: none;
+}
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical {
+ background: transparent;
+}
+
+QScrollBar:horizontal {
+ background: ${bg};
+ height: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:horizontal {
+ background: ${bg_hover};
+ min-width: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:horizontal:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:horizontal,
+QScrollBar::sub-line:horizontal {
+ width: 0;
+ border: none;
+}
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
+ background: transparent;
+}
+
+QScrollArea {
+ background: transparent;
+ border: none;
+}
+
+/* ---------- Menus ---------- */
+
+QMenuBar {
+ background-color: ${bg};
+ color: ${text};
+ border-bottom: 1px solid ${border};
+}
+QMenuBar::item {
+ background: transparent;
+ padding: 4px 10px;
+}
+QMenuBar::item:selected {
+ background-color: ${bg_hover};
+ color: ${text};
+}
+QMenuBar::item:pressed {
+ background-color: ${bg_active};
+}
+
+QMenu {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 0;
+}
+QMenu::item {
+ background: transparent;
+ padding: 5px 24px 5px 24px;
+}
+QMenu::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+QMenu::item:disabled {
+ color: ${text_disabled};
+}
+QMenu::separator {
+ height: 1px;
+ background: ${border};
+ margin: 4px 8px;
+}
+QMenu::icon {
+ padding-left: 6px;
+}
+
+/* ---------- Status bar ---------- */
+
+QStatusBar {
+ background-color: ${bg};
+ color: ${text_dim};
+ border-top: 1px solid ${border};
+}
+QStatusBar::item {
+ border: none;
+}
+
+/* ---------- Splitters ---------- */
+
+QSplitter::handle {
+ background: ${border};
+}
+QSplitter::handle:horizontal {
+ width: 2px;
+}
+QSplitter::handle:vertical {
+ height: 2px;
+}
+QSplitter::handle:hover {
+ background: ${accent};
+}
+
+/* ---------- Sliders ---------- */
+
+QSlider::groove:horizontal {
+ background: ${bg_subtle};
+ height: 4px;
+}
+QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+QSlider::handle:horizontal {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: -5px 0;
+}
+QSlider::handle:horizontal:hover {
+ background: ${accent_dim};
+}
+
+QSlider::groove:vertical {
+ background: ${bg_subtle};
+ width: 4px;
+}
+QSlider::handle:vertical {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: 0 -5px;
+}
+
+/* ---------- Progress ---------- */
+
+QProgressBar {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border};
+ text-align: center;
+ height: 6px;
+}
+QProgressBar::chunk {
+ background-color: ${accent};
+}
+
+/* ---------- Checkboxes & radio buttons ---------- */
+
+QCheckBox, QRadioButton {
+ background: transparent;
+ color: ${text};
+ spacing: 6px;
+}
+QCheckBox::indicator, QRadioButton::indicator {
+ width: 14px;
+ height: 14px;
+ background-color: ${bg_subtle};
+ border: 1px solid ${border_strong};
+}
+QCheckBox::indicator {
+}
+QRadioButton::indicator {
+ border-radius: 7px;
+}
+QCheckBox::indicator:hover, QRadioButton::indicator:hover {
+ border-color: ${accent};
+}
+QCheckBox::indicator:checked, QRadioButton::indicator:checked {
+ background-color: ${accent};
+ border-color: ${accent};
+}
+QCheckBox::indicator:disabled, QRadioButton::indicator:disabled {
+ background-color: ${bg_alt};
+ border-color: ${border};
+}
+
+/* ---------- Tooltips ---------- */
+
+QToolTip {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 6px;
+}
+
+/* ---------- Item views (lists, trees, tables) ---------- */
+
+QListView, QListWidget, QTreeView, QTreeWidget, QTableView, QTableWidget {
+ background-color: ${bg};
+ alternate-background-color: ${bg_alt};
+ color: ${text};
+ border: 1px solid ${border};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+}
+QListView::item, QListWidget::item,
+QTreeView::item, QTreeWidget::item,
+QTableView::item, QTableWidget::item {
+ padding: 4px;
+}
+QListView::item:hover, QListWidget::item:hover,
+QTreeView::item:hover, QTreeWidget::item:hover,
+QTableView::item:hover, QTableWidget::item:hover {
+ background-color: ${bg_hover};
+}
+QListView::item:selected, QListWidget::item:selected,
+QTreeView::item:selected, QTreeWidget::item:selected,
+QTableView::item:selected, QTableWidget::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+
+QHeaderView::section {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: none;
+ border-right: 1px solid ${border};
+ padding: 4px 8px;
+}
+QHeaderView::section:hover {
+ background-color: ${bg_hover};
+}
+
+/* ---------- Tabs ---------- */
+
+QTabWidget::pane {
+ border: 1px solid ${border};
+ top: -1px;
+}
+QTabBar::tab {
+ background: ${bg_subtle};
+ color: ${text_dim};
+ border: 1px solid ${border};
+ border-bottom: none;
+ padding: 6px 14px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+QTabBar::tab:selected {
+ background: ${bg};
+ color: ${text};
+ border-color: ${border_strong};
+}
+QTabBar::tab:hover:!selected {
+ background: ${bg_hover};
+ color: ${text};
+}
+
+/* ---------- Group boxes ---------- */
+
+QGroupBox {
+ background: transparent;
+ color: ${text};
+ border: 1px solid ${border};
+ margin-top: 10px;
+ padding-top: 8px;
+}
+QGroupBox::title {
+ subcontrol-origin: margin;
+ subcontrol-position: top left;
+ padding: 0 6px;
+ color: ${text_dim};
+}
+
+/* ---------- Frames ---------- */
+
+QFrame[frameShape="4"], /* HLine */
+QFrame[frameShape="5"] /* VLine */ {
+ background: ${border};
+ color: ${border};
+}
+
+/* ---------- Toolbars ---------- */
+
+QToolBar {
+ background: ${bg};
+ border: none;
+ spacing: 4px;
+ padding: 2px;
+}
+QToolBar::separator {
+ background: ${border};
+ width: 1px;
+ margin: 4px 4px;
+}
+
+/* ---------- Dock widgets ---------- */
+
+QDockWidget {
+ color: ${text};
+ titlebar-close-icon: none;
+}
+QDockWidget::title {
+ background: ${bg_subtle};
+ padding: 4px;
+ border: 1px solid ${border};
+}
+
+/* ---------- Rubber band (multi-select drag rectangle) ---------- */
+
+QRubberBand {
+ background: ${accent};
+ border: 1px solid ${accent};
+ /* Qt blends rubber band at ~30% so this reads as a translucent
+ * accent-tinted rectangle without needing rgba(). */
+}
+
+
+
+/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
+
+ThumbnailWidget {
+ qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
+ qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
+}
+
+/* ---------- Info panel tag category colors ---------- */
+
+InfoPanel {
+ qproperty-tagArtistColor: ${warning};
+ qproperty-tagCharacterColor: ${success};
+ qproperty-tagCopyrightColor: ${accent};
+ qproperty-tagSpeciesColor: ${danger};
+ qproperty-tagMetaColor: ${text_dim};
+ qproperty-tagLoreColor: ${text_dim};
+}
+
+/* ---------- Video player letterbox / pillarbox color (mpv background) ---------- */
+
+VideoPlayer {
+ qproperty-letterboxColor: ${bg};
+}
+
+/* ---------- Popout overlay bars (slideshow toolbar + slideshow controls + embedded preview controls) ---------- */
+/*
+ * The popout window's translucent toolbar (top) and transport controls
+ * (bottom) float over the video content. The bg color comes from the
+ * @palette overlay_bg slot. Children get the classic overlay treatment:
+ * transparent backgrounds, near-white text, hairline borders.
+ */
+
+QWidget#_slideshow_toolbar,
+QWidget#_slideshow_controls,
+QWidget#_preview_controls {
+ background: ${overlay_bg};
+}
+
+QWidget#_slideshow_toolbar *,
+QWidget#_slideshow_controls *,
+QWidget#_preview_controls * {
+ background: transparent;
+ color: white;
+ border: none;
+}
+
+QWidget#_slideshow_toolbar QPushButton,
+QWidget#_slideshow_controls QPushButton,
+QWidget#_preview_controls QPushButton {
+ background: transparent;
+ color: white;
+ border: 1px solid rgba(255, 255, 255, 80);
+ padding: 2px 6px;
+}
+QWidget#_slideshow_toolbar QPushButton:hover,
+QWidget#_slideshow_controls QPushButton:hover,
+QWidget#_preview_controls QPushButton:hover {
+ background: rgba(255, 255, 255, 30);
+}
+
+QWidget#_slideshow_toolbar QSlider::groove:horizontal,
+QWidget#_slideshow_controls QSlider::groove:horizontal,
+QWidget#_preview_controls QSlider::groove:horizontal {
+ background: rgba(255, 255, 255, 40);
+ height: 4px;
+}
+QWidget#_slideshow_toolbar QSlider::handle:horizontal,
+QWidget#_slideshow_controls QSlider::handle:horizontal,
+QWidget#_preview_controls QSlider::handle:horizontal {
+ background: ${accent};
+ width: 10px;
+ margin: -4px 0;
+}
+QWidget#_slideshow_toolbar QSlider::sub-page:horizontal,
+QWidget#_slideshow_controls QSlider::sub-page:horizontal,
+QWidget#_preview_controls QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+
+QWidget#_slideshow_toolbar QLabel,
+QWidget#_slideshow_controls QLabel,
+QWidget#_preview_controls QLabel {
+ background: transparent;
+ color: white;
+}
diff --git a/themes/solarized-dark.qss b/themes/solarized-dark-rounded.qss
similarity index 98%
rename from themes/solarized-dark.qss
rename to themes/solarized-dark-rounded.qss
index 7b80b60..c1086e5 100644
--- a/themes/solarized-dark.qss
+++ b/themes/solarized-dark-rounded.qss
@@ -1,6 +1,6 @@
/* booru-viewer — Solarized Dark
*
- * Edit the @palette block below to recolor this theme. The body uses
+ * Edit the @palette block below to recolor this rounded variant. The body uses
* ${...} placeholders that the app's _load_user_qss preprocessor
* substitutes at load time. See themes/README.md for the full list of
* placeholder names and what each one is used for.
@@ -515,6 +515,10 @@ QRubberBand {
ThumbnailWidget {
qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
}
/* ---------- Info panel tag category colors ---------- */
diff --git a/themes/solarized-dark-square.qss b/themes/solarized-dark-square.qss
new file mode 100644
index 0000000..1662351
--- /dev/null
+++ b/themes/solarized-dark-square.qss
@@ -0,0 +1,588 @@
+/* booru-viewer — Solarized Dark
+ *
+ * Edit the @palette block below to recolor this square variant. The body uses
+ * ${...} placeholders that the app's _load_user_qss preprocessor
+ * substitutes at load time. See themes/README.md for the full list of
+ * placeholder names and what each one is used for.
+ *
+ * The same dialect works in any custom.qss you put in your data dir.
+ */
+
+/* @palette
+ bg: #002b36
+ bg_alt: #001f27
+ bg_subtle: #073642
+ bg_hover: #0d4654
+ bg_active: #586e75
+ text: #93a1a1
+ text_dim: #839496
+ text_disabled: #586e75
+ border: #073642
+ border_strong: #0d4654
+ accent: #268bd2
+ accent_text: #002b36
+ accent_dim: #2aa198
+ link: #2aa198
+ danger: #dc322f
+ success: #859900
+ warning: #b58900
+ overlay_bg: rgba(0, 43, 54, 200)
+*/
+
+/* ---------- Base ---------- */
+
+QWidget {
+ background-color: ${bg};
+ color: ${text};
+ font-size: 13px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+
+QWidget:disabled {
+ color: ${text_disabled};
+}
+
+/* Labels should never paint an opaque background — they sit on top of
+ * other widgets in many places (toolbars, info panels, overlays). */
+QLabel {
+ background: transparent;
+}
+
+QMainWindow, QDialog {
+ background-color: ${bg};
+}
+
+/* ---------- Buttons ---------- */
+
+QPushButton {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 5px 12px;
+ min-height: 18px;
+}
+QPushButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${accent};
+}
+QPushButton:pressed {
+ background-color: ${bg_active};
+}
+QPushButton:checked {
+ background-color: ${accent};
+ color: ${accent_text};
+ border-color: ${accent};
+}
+QPushButton:checked:hover {
+ background-color: ${accent_dim};
+ border-color: ${accent_dim};
+}
+QPushButton:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+QPushButton:flat {
+ background: transparent;
+ border: none;
+}
+QPushButton:flat:hover {
+ background-color: ${bg_hover};
+}
+
+QToolButton {
+ background-color: transparent;
+ color: ${text};
+ border: 1px solid transparent;
+ padding: 4px;
+}
+QToolButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${border_strong};
+}
+QToolButton:pressed, QToolButton:checked {
+ background-color: ${bg_active};
+}
+
+/* ---------- Inputs ---------- */
+
+QLineEdit, QSpinBox, QDoubleSpinBox, QTextEdit, QPlainTextEdit {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ /* min-height ensures the painted text fits inside the widget bounds
+ * even when a parent layout (e.g. QFormLayout inside a QGroupBox)
+ * compresses the natural sizeHint. Without this, spinboxes in dense
+ * forms render with the top of the value text clipped. */
+ min-height: 20px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+QLineEdit:focus,
+QSpinBox:focus,
+QDoubleSpinBox:focus,
+QTextEdit:focus,
+QPlainTextEdit:focus {
+ border-color: ${accent};
+}
+QLineEdit:disabled,
+QSpinBox:disabled,
+QDoubleSpinBox:disabled,
+QTextEdit:disabled,
+QPlainTextEdit:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+
+QComboBox {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ min-height: 20px;
+}
+QComboBox:hover {
+ border-color: ${accent};
+}
+QComboBox:focus {
+ border-color: ${accent};
+}
+QComboBox::drop-down {
+ border: none;
+ width: 18px;
+}
+QComboBox QAbstractItemView {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+ padding: 2px;
+}
+
+/* ---------- Scrollbars ---------- */
+
+QScrollBar:vertical {
+ background: ${bg};
+ width: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:vertical {
+ background: ${bg_hover};
+ min-height: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:vertical:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:vertical,
+QScrollBar::sub-line:vertical {
+ height: 0;
+ border: none;
+}
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical {
+ background: transparent;
+}
+
+QScrollBar:horizontal {
+ background: ${bg};
+ height: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:horizontal {
+ background: ${bg_hover};
+ min-width: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:horizontal:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:horizontal,
+QScrollBar::sub-line:horizontal {
+ width: 0;
+ border: none;
+}
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
+ background: transparent;
+}
+
+QScrollArea {
+ background: transparent;
+ border: none;
+}
+
+/* ---------- Menus ---------- */
+
+QMenuBar {
+ background-color: ${bg};
+ color: ${text};
+ border-bottom: 1px solid ${border};
+}
+QMenuBar::item {
+ background: transparent;
+ padding: 4px 10px;
+}
+QMenuBar::item:selected {
+ background-color: ${bg_hover};
+ color: ${text};
+}
+QMenuBar::item:pressed {
+ background-color: ${bg_active};
+}
+
+QMenu {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 0;
+}
+QMenu::item {
+ background: transparent;
+ padding: 5px 24px 5px 24px;
+}
+QMenu::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+QMenu::item:disabled {
+ color: ${text_disabled};
+}
+QMenu::separator {
+ height: 1px;
+ background: ${border};
+ margin: 4px 8px;
+}
+QMenu::icon {
+ padding-left: 6px;
+}
+
+/* ---------- Status bar ---------- */
+
+QStatusBar {
+ background-color: ${bg};
+ color: ${text_dim};
+ border-top: 1px solid ${border};
+}
+QStatusBar::item {
+ border: none;
+}
+
+/* ---------- Splitters ---------- */
+
+QSplitter::handle {
+ background: ${border};
+}
+QSplitter::handle:horizontal {
+ width: 2px;
+}
+QSplitter::handle:vertical {
+ height: 2px;
+}
+QSplitter::handle:hover {
+ background: ${accent};
+}
+
+/* ---------- Sliders ---------- */
+
+QSlider::groove:horizontal {
+ background: ${bg_subtle};
+ height: 4px;
+}
+QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+QSlider::handle:horizontal {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: -5px 0;
+}
+QSlider::handle:horizontal:hover {
+ background: ${accent_dim};
+}
+
+QSlider::groove:vertical {
+ background: ${bg_subtle};
+ width: 4px;
+}
+QSlider::handle:vertical {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: 0 -5px;
+}
+
+/* ---------- Progress ---------- */
+
+QProgressBar {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border};
+ text-align: center;
+ height: 6px;
+}
+QProgressBar::chunk {
+ background-color: ${accent};
+}
+
+/* ---------- Checkboxes & radio buttons ---------- */
+
+QCheckBox, QRadioButton {
+ background: transparent;
+ color: ${text};
+ spacing: 6px;
+}
+QCheckBox::indicator, QRadioButton::indicator {
+ width: 14px;
+ height: 14px;
+ background-color: ${bg_subtle};
+ border: 1px solid ${border_strong};
+}
+QCheckBox::indicator {
+}
+QRadioButton::indicator {
+ border-radius: 7px;
+}
+QCheckBox::indicator:hover, QRadioButton::indicator:hover {
+ border-color: ${accent};
+}
+QCheckBox::indicator:checked, QRadioButton::indicator:checked {
+ background-color: ${accent};
+ border-color: ${accent};
+}
+QCheckBox::indicator:disabled, QRadioButton::indicator:disabled {
+ background-color: ${bg_alt};
+ border-color: ${border};
+}
+
+/* ---------- Tooltips ---------- */
+
+QToolTip {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 6px;
+}
+
+/* ---------- Item views (lists, trees, tables) ---------- */
+
+QListView, QListWidget, QTreeView, QTreeWidget, QTableView, QTableWidget {
+ background-color: ${bg};
+ alternate-background-color: ${bg_alt};
+ color: ${text};
+ border: 1px solid ${border};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+}
+QListView::item, QListWidget::item,
+QTreeView::item, QTreeWidget::item,
+QTableView::item, QTableWidget::item {
+ padding: 4px;
+}
+QListView::item:hover, QListWidget::item:hover,
+QTreeView::item:hover, QTreeWidget::item:hover,
+QTableView::item:hover, QTableWidget::item:hover {
+ background-color: ${bg_hover};
+}
+QListView::item:selected, QListWidget::item:selected,
+QTreeView::item:selected, QTreeWidget::item:selected,
+QTableView::item:selected, QTableWidget::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+
+QHeaderView::section {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: none;
+ border-right: 1px solid ${border};
+ padding: 4px 8px;
+}
+QHeaderView::section:hover {
+ background-color: ${bg_hover};
+}
+
+/* ---------- Tabs ---------- */
+
+QTabWidget::pane {
+ border: 1px solid ${border};
+ top: -1px;
+}
+QTabBar::tab {
+ background: ${bg_subtle};
+ color: ${text_dim};
+ border: 1px solid ${border};
+ border-bottom: none;
+ padding: 6px 14px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+QTabBar::tab:selected {
+ background: ${bg};
+ color: ${text};
+ border-color: ${border_strong};
+}
+QTabBar::tab:hover:!selected {
+ background: ${bg_hover};
+ color: ${text};
+}
+
+/* ---------- Group boxes ---------- */
+
+QGroupBox {
+ background: transparent;
+ color: ${text};
+ border: 1px solid ${border};
+ margin-top: 10px;
+ padding-top: 8px;
+}
+QGroupBox::title {
+ subcontrol-origin: margin;
+ subcontrol-position: top left;
+ padding: 0 6px;
+ color: ${text_dim};
+}
+
+/* ---------- Frames ---------- */
+
+QFrame[frameShape="4"], /* HLine */
+QFrame[frameShape="5"] /* VLine */ {
+ background: ${border};
+ color: ${border};
+}
+
+/* ---------- Toolbars ---------- */
+
+QToolBar {
+ background: ${bg};
+ border: none;
+ spacing: 4px;
+ padding: 2px;
+}
+QToolBar::separator {
+ background: ${border};
+ width: 1px;
+ margin: 4px 4px;
+}
+
+/* ---------- Dock widgets ---------- */
+
+QDockWidget {
+ color: ${text};
+ titlebar-close-icon: none;
+}
+QDockWidget::title {
+ background: ${bg_subtle};
+ padding: 4px;
+ border: 1px solid ${border};
+}
+
+/* ---------- Rubber band (multi-select drag rectangle) ---------- */
+
+QRubberBand {
+ background: ${accent};
+ border: 1px solid ${accent};
+ /* Qt blends rubber band at ~30% so this reads as a translucent
+ * accent-tinted rectangle without needing rgba(). */
+}
+
+
+
+/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
+
+ThumbnailWidget {
+ qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
+ qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
+}
+
+/* ---------- Info panel tag category colors ---------- */
+
+InfoPanel {
+ qproperty-tagArtistColor: ${warning};
+ qproperty-tagCharacterColor: ${success};
+ qproperty-tagCopyrightColor: ${accent};
+ qproperty-tagSpeciesColor: ${danger};
+ qproperty-tagMetaColor: ${text_dim};
+ qproperty-tagLoreColor: ${text_dim};
+}
+
+/* ---------- Video player letterbox / pillarbox color (mpv background) ---------- */
+
+VideoPlayer {
+ qproperty-letterboxColor: ${bg};
+}
+
+/* ---------- Popout overlay bars (slideshow toolbar + slideshow controls + embedded preview controls) ---------- */
+/*
+ * The popout window's translucent toolbar (top) and transport controls
+ * (bottom) float over the video content. The bg color comes from the
+ * @palette overlay_bg slot. Children get the classic overlay treatment:
+ * transparent backgrounds, near-white text, hairline borders.
+ */
+
+QWidget#_slideshow_toolbar,
+QWidget#_slideshow_controls,
+QWidget#_preview_controls {
+ background: ${overlay_bg};
+}
+
+QWidget#_slideshow_toolbar *,
+QWidget#_slideshow_controls *,
+QWidget#_preview_controls * {
+ background: transparent;
+ color: white;
+ border: none;
+}
+
+QWidget#_slideshow_toolbar QPushButton,
+QWidget#_slideshow_controls QPushButton,
+QWidget#_preview_controls QPushButton {
+ background: transparent;
+ color: white;
+ border: 1px solid rgba(255, 255, 255, 80);
+ padding: 2px 6px;
+}
+QWidget#_slideshow_toolbar QPushButton:hover,
+QWidget#_slideshow_controls QPushButton:hover,
+QWidget#_preview_controls QPushButton:hover {
+ background: rgba(255, 255, 255, 30);
+}
+
+QWidget#_slideshow_toolbar QSlider::groove:horizontal,
+QWidget#_slideshow_controls QSlider::groove:horizontal,
+QWidget#_preview_controls QSlider::groove:horizontal {
+ background: rgba(255, 255, 255, 40);
+ height: 4px;
+}
+QWidget#_slideshow_toolbar QSlider::handle:horizontal,
+QWidget#_slideshow_controls QSlider::handle:horizontal,
+QWidget#_preview_controls QSlider::handle:horizontal {
+ background: ${accent};
+ width: 10px;
+ margin: -4px 0;
+}
+QWidget#_slideshow_toolbar QSlider::sub-page:horizontal,
+QWidget#_slideshow_controls QSlider::sub-page:horizontal,
+QWidget#_preview_controls QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+
+QWidget#_slideshow_toolbar QLabel,
+QWidget#_slideshow_controls QLabel,
+QWidget#_preview_controls QLabel {
+ background: transparent;
+ color: white;
+}
diff --git a/themes/tokyo-night.qss b/themes/tokyo-night-rounded.qss
similarity index 98%
rename from themes/tokyo-night.qss
rename to themes/tokyo-night-rounded.qss
index 84b1d56..4665fb3 100644
--- a/themes/tokyo-night.qss
+++ b/themes/tokyo-night-rounded.qss
@@ -1,6 +1,6 @@
/* booru-viewer — Tokyo Night
*
- * Edit the @palette block below to recolor this theme. The body uses
+ * Edit the @palette block below to recolor this rounded variant. The body uses
* ${...} placeholders that the app's _load_user_qss preprocessor
* substitutes at load time. See themes/README.md for the full list of
* placeholder names and what each one is used for.
@@ -515,6 +515,10 @@ QRubberBand {
ThumbnailWidget {
qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
}
/* ---------- Info panel tag category colors ---------- */
diff --git a/themes/tokyo-night-square.qss b/themes/tokyo-night-square.qss
new file mode 100644
index 0000000..49ab3a6
--- /dev/null
+++ b/themes/tokyo-night-square.qss
@@ -0,0 +1,588 @@
+/* booru-viewer — Tokyo Night
+ *
+ * Edit the @palette block below to recolor this square variant. The body uses
+ * ${...} placeholders that the app's _load_user_qss preprocessor
+ * substitutes at load time. See themes/README.md for the full list of
+ * placeholder names and what each one is used for.
+ *
+ * The same dialect works in any custom.qss you put in your data dir.
+ */
+
+/* @palette
+ bg: #1a1b26
+ bg_alt: #16161e
+ bg_subtle: #24283b
+ bg_hover: #292e42
+ bg_active: #3b4261
+ text: #c0caf5
+ text_dim: #a9b1d6
+ text_disabled: #565f89
+ border: #24283b
+ border_strong: #292e42
+ accent: #7aa2f7
+ accent_text: #1a1b26
+ accent_dim: #7dcfff
+ link: #7dcfff
+ danger: #f7768e
+ success: #9ece6a
+ warning: #e0af68
+ overlay_bg: rgba(26, 27, 38, 200)
+*/
+
+/* ---------- Base ---------- */
+
+QWidget {
+ background-color: ${bg};
+ color: ${text};
+ font-size: 13px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+
+QWidget:disabled {
+ color: ${text_disabled};
+}
+
+/* Labels should never paint an opaque background — they sit on top of
+ * other widgets in many places (toolbars, info panels, overlays). */
+QLabel {
+ background: transparent;
+}
+
+QMainWindow, QDialog {
+ background-color: ${bg};
+}
+
+/* ---------- Buttons ---------- */
+
+QPushButton {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 5px 12px;
+ min-height: 18px;
+}
+QPushButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${accent};
+}
+QPushButton:pressed {
+ background-color: ${bg_active};
+}
+QPushButton:checked {
+ background-color: ${accent};
+ color: ${accent_text};
+ border-color: ${accent};
+}
+QPushButton:checked:hover {
+ background-color: ${accent_dim};
+ border-color: ${accent_dim};
+}
+QPushButton:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+QPushButton:flat {
+ background: transparent;
+ border: none;
+}
+QPushButton:flat:hover {
+ background-color: ${bg_hover};
+}
+
+QToolButton {
+ background-color: transparent;
+ color: ${text};
+ border: 1px solid transparent;
+ padding: 4px;
+}
+QToolButton:hover {
+ background-color: ${bg_hover};
+ border-color: ${border_strong};
+}
+QToolButton:pressed, QToolButton:checked {
+ background-color: ${bg_active};
+}
+
+/* ---------- Inputs ---------- */
+
+QLineEdit, QSpinBox, QDoubleSpinBox, QTextEdit, QPlainTextEdit {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ /* min-height ensures the painted text fits inside the widget bounds
+ * even when a parent layout (e.g. QFormLayout inside a QGroupBox)
+ * compresses the natural sizeHint. Without this, spinboxes in dense
+ * forms render with the top of the value text clipped. */
+ min-height: 20px;
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+}
+QLineEdit:focus,
+QSpinBox:focus,
+QDoubleSpinBox:focus,
+QTextEdit:focus,
+QPlainTextEdit:focus {
+ border-color: ${accent};
+}
+QLineEdit:disabled,
+QSpinBox:disabled,
+QDoubleSpinBox:disabled,
+QTextEdit:disabled,
+QPlainTextEdit:disabled {
+ background-color: ${bg_alt};
+ color: ${text_disabled};
+ border-color: ${border};
+}
+
+QComboBox {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 8px;
+ min-height: 20px;
+}
+QComboBox:hover {
+ border-color: ${accent};
+}
+QComboBox:focus {
+ border-color: ${accent};
+}
+QComboBox::drop-down {
+ border: none;
+ width: 18px;
+}
+QComboBox QAbstractItemView {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+ padding: 2px;
+}
+
+/* ---------- Scrollbars ---------- */
+
+QScrollBar:vertical {
+ background: ${bg};
+ width: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:vertical {
+ background: ${bg_hover};
+ min-height: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:vertical:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:vertical,
+QScrollBar::sub-line:vertical {
+ height: 0;
+ border: none;
+}
+QScrollBar::add-page:vertical,
+QScrollBar::sub-page:vertical {
+ background: transparent;
+}
+
+QScrollBar:horizontal {
+ background: ${bg};
+ height: 10px;
+ border: none;
+ margin: 0;
+}
+QScrollBar::handle:horizontal {
+ background: ${bg_hover};
+ min-width: 24px;
+ margin: 1px;
+}
+QScrollBar::handle:horizontal:hover {
+ background: ${bg_active};
+}
+QScrollBar::add-line:horizontal,
+QScrollBar::sub-line:horizontal {
+ width: 0;
+ border: none;
+}
+QScrollBar::add-page:horizontal,
+QScrollBar::sub-page:horizontal {
+ background: transparent;
+}
+
+QScrollArea {
+ background: transparent;
+ border: none;
+}
+
+/* ---------- Menus ---------- */
+
+QMenuBar {
+ background-color: ${bg};
+ color: ${text};
+ border-bottom: 1px solid ${border};
+}
+QMenuBar::item {
+ background: transparent;
+ padding: 4px 10px;
+}
+QMenuBar::item:selected {
+ background-color: ${bg_hover};
+ color: ${text};
+}
+QMenuBar::item:pressed {
+ background-color: ${bg_active};
+}
+
+QMenu {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 0;
+}
+QMenu::item {
+ background: transparent;
+ padding: 5px 24px 5px 24px;
+}
+QMenu::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+QMenu::item:disabled {
+ color: ${text_disabled};
+}
+QMenu::separator {
+ height: 1px;
+ background: ${border};
+ margin: 4px 8px;
+}
+QMenu::icon {
+ padding-left: 6px;
+}
+
+/* ---------- Status bar ---------- */
+
+QStatusBar {
+ background-color: ${bg};
+ color: ${text_dim};
+ border-top: 1px solid ${border};
+}
+QStatusBar::item {
+ border: none;
+}
+
+/* ---------- Splitters ---------- */
+
+QSplitter::handle {
+ background: ${border};
+}
+QSplitter::handle:horizontal {
+ width: 2px;
+}
+QSplitter::handle:vertical {
+ height: 2px;
+}
+QSplitter::handle:hover {
+ background: ${accent};
+}
+
+/* ---------- Sliders ---------- */
+
+QSlider::groove:horizontal {
+ background: ${bg_subtle};
+ height: 4px;
+}
+QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+QSlider::handle:horizontal {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: -5px 0;
+}
+QSlider::handle:horizontal:hover {
+ background: ${accent_dim};
+}
+
+QSlider::groove:vertical {
+ background: ${bg_subtle};
+ width: 4px;
+}
+QSlider::handle:vertical {
+ background: ${accent};
+ width: 12px;
+ height: 12px;
+ margin: 0 -5px;
+}
+
+/* ---------- Progress ---------- */
+
+QProgressBar {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border};
+ text-align: center;
+ height: 6px;
+}
+QProgressBar::chunk {
+ background-color: ${accent};
+}
+
+/* ---------- Checkboxes & radio buttons ---------- */
+
+QCheckBox, QRadioButton {
+ background: transparent;
+ color: ${text};
+ spacing: 6px;
+}
+QCheckBox::indicator, QRadioButton::indicator {
+ width: 14px;
+ height: 14px;
+ background-color: ${bg_subtle};
+ border: 1px solid ${border_strong};
+}
+QCheckBox::indicator {
+}
+QRadioButton::indicator {
+ border-radius: 7px;
+}
+QCheckBox::indicator:hover, QRadioButton::indicator:hover {
+ border-color: ${accent};
+}
+QCheckBox::indicator:checked, QRadioButton::indicator:checked {
+ background-color: ${accent};
+ border-color: ${accent};
+}
+QCheckBox::indicator:disabled, QRadioButton::indicator:disabled {
+ background-color: ${bg_alt};
+ border-color: ${border};
+}
+
+/* ---------- Tooltips ---------- */
+
+QToolTip {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: 1px solid ${border_strong};
+ padding: 4px 6px;
+}
+
+/* ---------- Item views (lists, trees, tables) ---------- */
+
+QListView, QListWidget, QTreeView, QTreeWidget, QTableView, QTableWidget {
+ background-color: ${bg};
+ alternate-background-color: ${bg_alt};
+ color: ${text};
+ border: 1px solid ${border};
+ selection-background-color: ${accent};
+ selection-color: ${accent_text};
+ outline: none;
+}
+QListView::item, QListWidget::item,
+QTreeView::item, QTreeWidget::item,
+QTableView::item, QTableWidget::item {
+ padding: 4px;
+}
+QListView::item:hover, QListWidget::item:hover,
+QTreeView::item:hover, QTreeWidget::item:hover,
+QTableView::item:hover, QTableWidget::item:hover {
+ background-color: ${bg_hover};
+}
+QListView::item:selected, QListWidget::item:selected,
+QTreeView::item:selected, QTreeWidget::item:selected,
+QTableView::item:selected, QTableWidget::item:selected {
+ background-color: ${accent};
+ color: ${accent_text};
+}
+
+QHeaderView::section {
+ background-color: ${bg_subtle};
+ color: ${text};
+ border: none;
+ border-right: 1px solid ${border};
+ padding: 4px 8px;
+}
+QHeaderView::section:hover {
+ background-color: ${bg_hover};
+}
+
+/* ---------- Tabs ---------- */
+
+QTabWidget::pane {
+ border: 1px solid ${border};
+ top: -1px;
+}
+QTabBar::tab {
+ background: ${bg_subtle};
+ color: ${text_dim};
+ border: 1px solid ${border};
+ border-bottom: none;
+ padding: 6px 14px;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+QTabBar::tab:selected {
+ background: ${bg};
+ color: ${text};
+ border-color: ${border_strong};
+}
+QTabBar::tab:hover:!selected {
+ background: ${bg_hover};
+ color: ${text};
+}
+
+/* ---------- Group boxes ---------- */
+
+QGroupBox {
+ background: transparent;
+ color: ${text};
+ border: 1px solid ${border};
+ margin-top: 10px;
+ padding-top: 8px;
+}
+QGroupBox::title {
+ subcontrol-origin: margin;
+ subcontrol-position: top left;
+ padding: 0 6px;
+ color: ${text_dim};
+}
+
+/* ---------- Frames ---------- */
+
+QFrame[frameShape="4"], /* HLine */
+QFrame[frameShape="5"] /* VLine */ {
+ background: ${border};
+ color: ${border};
+}
+
+/* ---------- Toolbars ---------- */
+
+QToolBar {
+ background: ${bg};
+ border: none;
+ spacing: 4px;
+ padding: 2px;
+}
+QToolBar::separator {
+ background: ${border};
+ width: 1px;
+ margin: 4px 4px;
+}
+
+/* ---------- Dock widgets ---------- */
+
+QDockWidget {
+ color: ${text};
+ titlebar-close-icon: none;
+}
+QDockWidget::title {
+ background: ${bg_subtle};
+ padding: 4px;
+ border: 1px solid ${border};
+}
+
+/* ---------- Rubber band (multi-select drag rectangle) ---------- */
+
+QRubberBand {
+ background: ${accent};
+ border: 1px solid ${accent};
+ /* Qt blends rubber band at ~30% so this reads as a translucent
+ * accent-tinted rectangle without needing rgba(). */
+}
+
+
+
+/* ---------- Thumbnail dot indicators (Qt properties on ThumbnailWidget) ---------- */
+
+ThumbnailWidget {
+ qproperty-savedColor: #22cc22; /* green dot: saved to library — universal "confirmed" feel */
+ qproperty-bookmarkedColor: #ffcc00; /* yellow star: bookmarked */
+ qproperty-selectionColor: ${accent};
+ qproperty-multiSelectColor: ${accent_dim};
+ qproperty-hoverColor: ${accent};
+ qproperty-idleColor: ${border_strong};
+}
+
+/* ---------- Info panel tag category colors ---------- */
+
+InfoPanel {
+ qproperty-tagArtistColor: ${warning};
+ qproperty-tagCharacterColor: ${success};
+ qproperty-tagCopyrightColor: ${accent};
+ qproperty-tagSpeciesColor: ${danger};
+ qproperty-tagMetaColor: ${text_dim};
+ qproperty-tagLoreColor: ${text_dim};
+}
+
+/* ---------- Video player letterbox / pillarbox color (mpv background) ---------- */
+
+VideoPlayer {
+ qproperty-letterboxColor: ${bg};
+}
+
+/* ---------- Popout overlay bars (slideshow toolbar + slideshow controls + embedded preview controls) ---------- */
+/*
+ * The popout window's translucent toolbar (top) and transport controls
+ * (bottom) float over the video content. The bg color comes from the
+ * @palette overlay_bg slot. Children get the classic overlay treatment:
+ * transparent backgrounds, near-white text, hairline borders.
+ */
+
+QWidget#_slideshow_toolbar,
+QWidget#_slideshow_controls,
+QWidget#_preview_controls {
+ background: ${overlay_bg};
+}
+
+QWidget#_slideshow_toolbar *,
+QWidget#_slideshow_controls *,
+QWidget#_preview_controls * {
+ background: transparent;
+ color: white;
+ border: none;
+}
+
+QWidget#_slideshow_toolbar QPushButton,
+QWidget#_slideshow_controls QPushButton,
+QWidget#_preview_controls QPushButton {
+ background: transparent;
+ color: white;
+ border: 1px solid rgba(255, 255, 255, 80);
+ padding: 2px 6px;
+}
+QWidget#_slideshow_toolbar QPushButton:hover,
+QWidget#_slideshow_controls QPushButton:hover,
+QWidget#_preview_controls QPushButton:hover {
+ background: rgba(255, 255, 255, 30);
+}
+
+QWidget#_slideshow_toolbar QSlider::groove:horizontal,
+QWidget#_slideshow_controls QSlider::groove:horizontal,
+QWidget#_preview_controls QSlider::groove:horizontal {
+ background: rgba(255, 255, 255, 40);
+ height: 4px;
+}
+QWidget#_slideshow_toolbar QSlider::handle:horizontal,
+QWidget#_slideshow_controls QSlider::handle:horizontal,
+QWidget#_preview_controls QSlider::handle:horizontal {
+ background: ${accent};
+ width: 10px;
+ margin: -4px 0;
+}
+QWidget#_slideshow_toolbar QSlider::sub-page:horizontal,
+QWidget#_slideshow_controls QSlider::sub-page:horizontal,
+QWidget#_preview_controls QSlider::sub-page:horizontal {
+ background: ${accent};
+}
+
+QWidget#_slideshow_toolbar QLabel,
+QWidget#_slideshow_controls QLabel,
+QWidget#_preview_controls QLabel {
+ background: transparent;
+ color: white;
+}