diff --git a/themes/Theme-RoundedYellow/README.md b/themes/Theme-RoundedYellow/README.md
index b035ce43..53968696 100644
--- a/themes/Theme-RoundedYellow/README.md
+++ b/themes/Theme-RoundedYellow/README.md
@@ -2,8 +2,18 @@
https://discourse.stashapp.cc/t/rounded-yellow/1431
-A theme with yellow accent colour and rounded corners.
+A near-black theme with charcoal cards, large rounded corners and one warm yellow for everything active. Version 2.0 refreshes the theme for Stash v0.31: two radii (6px for controls, 20px for cards, panels, menus and dialogs), the active page in yellow with a yellow underline, yellow-filled primary buttons with dark text, covers that fade into the card above a translucent footer band, bordered toolbar boxes with a yellow-filled active view, yellow toggles and a yellow Settings nav block, and styling for the newer parts of Stash (filter sidebar, selection toolbar, performer header, settings, dialogs). The stock blue no longer shows through.
-## Preview
-
-
+## Screenshots
+
+Taken on Stash v0.31.1 with demo content: fictional titles and names, blurred openly licensed photos (credits on the [screenshots branch](https://github.com/nexalapp/CommunityScripts/tree/screenshots)).
+
+| Scenes | Scene |
+|---|---|
+|  |  |
+
+| Performer | Studios |
+|---|---|
+|  |  |
+
+
diff --git a/themes/Theme-RoundedYellow/Theme-RoundedYellow.css b/themes/Theme-RoundedYellow/Theme-RoundedYellow.css
index 7a5760f2..81d5c922 100644
--- a/themes/Theme-RoundedYellow/Theme-RoundedYellow.css
+++ b/themes/Theme-RoundedYellow/Theme-RoundedYellow.css
@@ -1,183 +1,1310 @@
+/*
+Rounded Yellow, refreshed for Stash v0.31.
+Near-black ground, charcoal cards with large rounded corners, and one warm
+yellow for everything active.
+*/
+
:root {
- --bgcol: #101118;
- --searchbgcol: #1b1c28;
- --btnbordercol: #202b33;
- --secbtncol: #171822;
- --btnaccentcol: #cfad0b;
- --cardbgcol: #1f282c;
- --navbarcol: #212529;
+ --ry-bg: #13141c; /* page, nav */
+ --ry-bar: #1b1f24; /* sidebar, menus on phones */
+ --ry-card: #1b1f24; /* cards, toolbar boxes, menus */
+ --ry-raised: #262a31; /* secondary buttons, hover */
+ --ry-line: rgba(255, 255, 255, 0.08); /* every hairline */
+ --ry-text: #f3f2ee;
+ --ry-text-2: #b5b3ad;
+ --ry-text-3: #8c8a84;
+ --ry-yellow: #d9a800; /* fills, rings, toggles */
+ --ry-yellow-text: #f2c230; /* yellow text, AA on the dark ground */
+ --ry-ink: #1a1400; /* text on a yellow fill */
+ --ry-danger: #d9363e;
+ --ry-radius: 6px; /* controls and buttons */
+ --ry-radius-sm: 4px;
+ --ry-radius-card: 20px; /* cards, panels, menus, dialogs */
}
body {
- background-color: var(--bgcol);
+ color: var(--ry-text);
+ background-color: var(--ry-bg);
}
-.bg-secondary {
- background-color: var(--searchbgcol) !important;
+.bg-dark {
+ background-color: var(--ry-bg) !important;
}
-.pagination .btn:first-child {
- border-left: 1px solid var(--btnbordercol);
-}
-.pagination .btn:last-child {
- border-right: 1px solid var(--btnbordercol);
+.card {
+ background-color: var(--ry-card);
+ border: 1px solid var(--ry-line);
+ border-radius: var(--ry-radius-card);
+ box-shadow: none;
}
-.btn-secondary {
- border-color: var(--btnbordercol);
- background-color: var(--bgcol);
+.bg-secondary {
+ background-color: var(--ry-card) !important;
}
-.btn-secondary:disabled {
- border-color: var(--btnbordercol);
- background-color: var(--secbtncol);
+.text-white {
+ color: var(--ry-text) !important;
}
-.btn-secondary:not(:disabled):not(.disabled):active,
-.btn-secondary:not(:disabled):not(.disabled).active,
-.show > .btn-secondary.dropdown-toggle {
- background-color: var(--secbtncol);
- border: 1px solid var(--btnbordercol);
- color: var(--btnaccentcol);
- border-bottom: 3px solid var(--btnaccentcol);
+.border-secondary {
+ border-color: var(--ry-line) !important;
}
-.card {
- background-color: var(--cardbgcol);
- border-radius: 30px;
+.btn-secondary {
+ color: var(--ry-text);
+ background-color: var(--ry-card);
+ border-color: var(--ry-line);
}
-.progress-indicator {
- background-color: var(--btnaccentcol);
+.btn-secondary:hover {
+ color: var(--ry-text);
+ background-color: var(--ry-raised);
+ border-color: var(--ry-line);
}
-.bg-dark {
- background-color: var(--navbarcol) !important;
+a {
+ color: var(--ry-text-2);
}
-.btn.active:not(.disabled),
-.btn.active.minimal:not(.disabled) {
- background-color: transparent;
- color: var(--btnaccentcol);
- border-bottom: 3px solid var(--btnaccentcol);
+.btn.active {
+ background-color: var(--ry-raised);
+ color: var(--ry-yellow-text);
}
+/* Primary actions: yellow fill with dark text; Delete filled red */
.btn-primary {
- background-color: var(--btnaccentcol);
- border-color: var(--btnaccentcol);
+ color: var(--ry-ink);
+ background-color: var(--ry-yellow);
+ border-color: var(--ry-yellow);
+}
+
+.btn-primary:hover,
+.btn-primary:focus {
+ color: var(--ry-ink);
+ background-color: var(--ry-yellow-text);
+ border-color: var(--ry-yellow-text);
}
-.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:not(:disabled):not(.disabled).active,
+.btn-primary:not(:disabled):not(.disabled):active,
.show > .btn-primary.dropdown-toggle {
+ color: var(--ry-ink);
+ background-color: var(--ry-yellow-text);
+ border-color: var(--ry-yellow-text);
+}
+
+.btn-danger {
+ color: #fff;
+ background-color: var(--ry-danger);
+ border-color: var(--ry-danger);
+}
+
+.nav-tabs {
+ border-bottom: 1px solid var(--ry-line);
+}
+
+.nav-tabs .nav-link {
+ outline: 0;
+ color: var(--ry-text-2);
+ border: 0;
+ border-radius: var(--ry-radius-sm) var(--ry-radius-sm) 0 0;
+}
+
+.nav-tabs .nav-link.active,
+.nav-tabs .nav-link.active:hover {
+ color: var(--ry-text);
background-color: transparent;
- border-color: var(--btnaccentcol);
+ border-bottom: 2px solid var(--ry-yellow);
+ outline: 0;
}
-.btn-primary:not(:disabled):not(.disabled):active:focus,
-.btn-primary:not(:disabled):not(.disabled).active:focus,
-.show > .btn-primary.dropdown-toggle:focus {
- box-shadow: 0 0 0 0;
+.btn-primary.btn.donate.minimal {
+ display: none;
}
-.btn-primary:focus,
-.btn-primary.focus {
- background-color: var(--btnaccentcol);
- border-color: var(--btnaccentcol);
- box-shadow: 0 0 0 0;
+.btn-primary.btn.help-button.minimal {
+ display: none;
}
-.btn-primary:hover {
- color: #fff;
- background-color: var(--btnaccentcol);
- border-color: var(--btnaccentcol);
+.changelog {
+ display: none;
}
-div.react-select__menu,
-div.dropdown-menu {
- background-color: var(--bgcol);
- color: #f5f8fa;
- z-index: 1600;
+.input-control,
+.input-control:focus,
+.form-control,
+.form-control:focus {
+ color: var(--ry-text);
+ background-color: var(--ry-card);
+ border-color: var(--ry-line);
}
-.modal-header,
-.modal-body,
-.modal-footer {
- background-color: var(--bgcol);
- color: #f5f8fa;
+#performer-page .image-container .performer {
+ background-color: rgba(0, 0, 0, 0.45);
+ box-shadow: 0 0 2px rgba(0, 0, 0, 0.35);
}
-.edit-filter-dialog .criterion-list .card .filter-item-header:focus {
- border-color: var(--btnaccentcol);
- border-radius: calc(0.375rem - 1px);
- box-shadow: inset 0 0 0 0.1rem var(--btnaccentcol);
- outline: 0;
+/* Settings: the active item on a yellow block */
+.nav-pills .nav-link {
+ color: var(--ry-text-2);
+ border-radius: var(--ry-radius-sm);
}
-.nav-tabs .nav-link.active {
- border-bottom: 2px solid;
- color: var(--btnaccentcol);
+.nav-pills .nav-link.active,
+.nav-pills .show > .nav-link {
+ color: var(--ry-ink);
+ background-color: var(--ry-yellow);
}
-.nav-tabs .nav-link.active:hover {
- border-bottom-color: var(--btnaccentcol);
- cursor: default;
+input[type="range"],
+input[type="checkbox"] {
+ accent-color: var(--ry-yellow);
}
-.job-table.card {
- background-color: var(--bgcol);
- height: 10em;
- margin-bottom: 30px;
- overflow-y: auto;
- padding: 0.5rem 15px;
+input[type="range"]::-moz-range-track {
+ background: hsla(0, 0%, 100%, 0.25);
+}
+
+input[type="range"]::-moz-range-thumb {
+ background: var(--ry-text);
+}
+
+div.react-select__control {
+ background-color: var(--ry-card);
+ color: var(--ry-text);
+ border-color: var(--ry-line);
+ cursor: pointer;
+}
+
+div.react-select__menu {
+ background-color: var(--ry-card);
+}
+
+.scene-wall-item-text-container {
+ background: radial-gradient(
+ farthest-corner at 50% 50%,
+ rgba(50, 50, 50, 0.5) 50%,
+ #323232 100%
+ );
+ color: var(--ry-text);
+}
+
+.btn-link {
+ font-weight: 500;
+ color: var(--ry-yellow-text);
+ text-decoration: none;
+}
+
+/* Top nav: plain labels, the active page in yellow with a yellow underline */
+button.minimal.brand-link.d-none.d-md-inline-block.btn.btn-primary {
+ color: var(--ry-text);
+ font-weight: 600;
+ border: 0;
+}
+
+a.minimal {
+ font-weight: 500;
+ color: var(--ry-text);
+}
+
+a:hover {
+ color: var(--ry-text);
+}
+
+option {
+ background-color: var(--ry-card);
+}
+
+.scrubber-tags-background {
+ background-color: var(--ry-raised);
+}
+
+/* Top-right icons: neutral, not the stock blue (or the old green logout) */
+.navbar-buttons .btn.minimal,
+.btn-primary.btn.settings-button.minimal,
+.btn-primary.btn.logout-button.minimal {
+ color: var(--ry-text-2);
+ background-color: transparent;
+ border-color: transparent;
+}
+
+.scrubber-viewport {
+ background-color: var(--ry-bar);
+}
+
+/* ---------- Stash v0.29+ refresh ---------- */
+
+.navbar {
+ border-bottom: 1px solid var(--ry-line);
+}
+.navbar-collapse > .navbar-nav > div > a {
+ display: flex !important;
+ flex-direction: row !important; /* stock stacks icon over label */
+ align-items: center;
+ height: 32px;
+ padding: 0 12px !important;
+ border-radius: var(--ry-radius);
+ font-size: 13px;
+}
+.navbar-collapse > .navbar-nav > div > a.active {
+ color: var(--ry-yellow-text) !important;
+ background-color: transparent !important;
+}
+@media (min-width: 1200px) {
+ .navbar-collapse > .navbar-nav > div > a {
+ position: relative;
+ }
+ .navbar-collapse > .navbar-nav > div > a.active::after {
+ content: "";
+ position: absolute;
+ left: 12px;
+ right: 12px;
+ bottom: var(--ry-nav-underline, -9px); /* on the bar's bottom edge */
+ height: 2px;
+ background-color: var(--ry-yellow);
+ }
+}
+@media (min-width: 1200px) {
+ .navbar-collapse > .navbar-nav > div > a svg {
+ display: none !important; /* words only on desktop */
+ }
+}
+.top-nav a[href$="/new"] .btn {
+ color: var(--ry-ink);
+ background-color: var(--ry-yellow);
+ border: 1px solid var(--ry-yellow);
+ font-weight: 600;
+}
+
+/* List toolbar: dark bordered 34px boxes, light glyphs, yellow-filled active view */
+.filtered-list-toolbar {
+ background-color: transparent !important;
+ gap: 8px;
+}
+.filtered-list-toolbar .btn-group,
+.filtered-list-toolbar .sort-by-select {
+ height: 34px;
+ background-color: var(--ry-card);
+ border: 1px solid var(--ry-line);
+ border-radius: var(--ry-radius);
+ padding: 2px;
+ gap: 2px;
+ align-items: center;
+}
+.filtered-list-toolbar .btn-group .btn-group {
+ border: 0;
+ padding: 0;
+ height: auto;
+ background: none;
+}
+.filtered-list-toolbar .btn-group .btn,
+.filtered-list-toolbar .sort-by-select .btn {
+ height: 28px !important; /* the saved-filter button sits one group deeper */
+ padding: 0 9px;
+ color: var(--ry-text);
+ border: 0 !important;
+ border-radius: var(--ry-radius-sm) !important;
+ background: none !important;
+ box-shadow: none !important;
+}
+.filtered-list-toolbar .btn-group .btn:hover {
+ background-color: var(--ry-raised) !important;
+}
+.filtered-list-toolbar .btn-group .btn.active {
+ color: var(--ry-ink) !important;
+ background-color: var(--ry-yellow) !important;
+}
+.filtered-list-toolbar .btn-group .btn-danger {
+ color: #fff !important;
+ background-color: var(--ry-danger) !important;
+}
+.filtered-list-toolbar .search-term-input .form-control,
+.filtered-list-toolbar .page-size-selector select {
+ height: 34px;
+ background-color: var(--ry-card) !important;
+ border: 1px solid var(--ry-line) !important;
+ border-radius: var(--ry-radius) !important;
+}
+.filtered-list-toolbar .page-size-selector select {
+ color: var(--ry-text);
+}
+.filtered-list-toolbar.has-selection .selected-items-info span {
+ color: var(--ry-yellow-text);
+ font-weight: 600;
+}
+.item-list-container .filtered-list-toolbar.has-selection {
+ background-color: var(--ry-bg) !important;
+ border-bottom: 1px solid var(--ry-line);
+}
+.sidebar-toggle-button-container .sidebar-toggle-button {
+ width: 34px;
+ height: 34px;
+ padding: 0;
+ margin-left: 0 !important; /* stock hangs it half off the page */
+ color: var(--ry-text);
+ background-color: var(--ry-card) !important;
+ border: 1px solid var(--ry-line) !important;
+ border-radius: var(--ry-radius) !important;
+ opacity: 1;
+}
+.sidebar-pane .sidebar,
+.sidebar .sidebar-footer,
+.sidebar-toolbar {
+ background-color: var(--ry-bar) !important;
+}
+.sidebar-pane .sidebar {
+ border-right: 1px solid var(--ry-line);
+}
+.zoom-slider {
+ accent-color: var(--ry-yellow);
+}
+/* Size slider: yellow track, white thumb (stock is blue) */
+input[type="range"].zoom-slider::-webkit-slider-runnable-track {
+ height: 4px;
+ border-radius: 2px;
+ background: var(--ry-yellow);
+}
+input[type="range"].zoom-slider::-webkit-slider-thumb {
+ -webkit-appearance: none;
+ width: 14px;
+ height: 14px;
+ margin-top: -5px;
+ border: 0;
+ border-radius: 50%;
+ background: var(--ry-text) !important;
+}
+.zoom-slider::-moz-range-track {
+ height: 4px;
+ background: var(--ry-yellow) !important;
+}
+.zoom-slider::-moz-range-thumb {
+ border: 0;
+ background: var(--ry-text);
+}
+
+/* Pagination centred, with the result count on the same row; the floating
+ bottom pagination stays */
+.pagination-index-container {
+ display: grid;
+ grid-template-columns: 1fr auto 1fr;
+ align-items: center;
+ gap: 12px;
+ margin-top: 10px;
+}
+.pagination-index-container > .pagination {
+ grid-column: 2;
+ margin: 0 !important;
+}
+.pagination-index-container > .paginationIndex {
+ grid-column: 3;
+ justify-self: end;
+ margin: 0 !important;
+ font-size: 13px;
+ color: var(--ry-text-2);
+}
+.pagination-index-container > .paginationIndex:only-child {
+ grid-column: 1 / -1;
+ justify-self: center;
+}
+.pagination.btn-group {
+ background-color: var(--ry-card);
+ border: 1px solid var(--ry-line);
+ border-radius: var(--ry-radius);
+ padding: 2px;
+ gap: 2px;
+}
+.pagination .btn,
+.pagination .btn:first-child,
+.pagination .btn:last-child {
+ color: var(--ry-text-2);
+ border: 0 !important;
+ border-radius: var(--ry-radius-sm) !important;
+ background: none;
+}
+.pagination .btn:hover {
+ color: var(--ry-text);
+ background-color: var(--ry-raised);
+}
+.pagination .btn.active,
+.pagination .btn:disabled {
+ color: var(--ry-text);
+}
+@media (max-width: 575.98px) {
+ .pagination-index-container {
+ grid-template-columns: 1fr;
+ justify-items: center;
+ }
+ .pagination-index-container > .pagination,
+ .pagination-index-container > .paginationIndex {
+ grid-column: 1;
+ justify-self: center;
+ }
}
-.progress-bar {
+/* Cards: hover lifts 2px with a yellow hairline; selection is a 2px yellow
+ ring; the cover fades into the card above a translucent footer band */
+.grid-card {
+ overflow: hidden;
+ border-color: transparent;
display: flex;
flex-direction: column;
- justify-content: center;
+ padding: 0;
+ transition: transform 0.2s cubic-bezier(0.2, 0.7, 0.2, 1), box-shadow 0.2s, border-color 0.2s;
+}
+.grid-card:hover {
+ transform: translateY(-2px);
+ border-color: rgba(217, 168, 0, 0.6);
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
+}
+.grid-card:has(.card-check:checked) {
+ border-color: var(--ry-yellow);
+ box-shadow: 0 0 0 1px var(--ry-yellow);
+}
+.grid-card .thumbnail-section {
+ position: relative;
overflow: hidden;
+ flex: none; /* never squeezed by the text below it */
+}
+.scene-card .thumbnail-section::after,
+.gallery-card .thumbnail-section::after,
+.group-card .thumbnail-section::after {
+ content: "";
+ position: absolute;
+ inset: 0;
+ pointer-events: none;
+ background: linear-gradient(180deg, transparent 45%, var(--ry-card));
+}
+.grid-card .scene-specs-overlay,
+.grid-card .studio-overlay,
+.grid-card .favorite-button,
+.grid-card .card-check {
+ z-index: 2;
+}
+.grid-card .card-section {
+ padding: 12px 14px 12px !important; /* keeps the text off the footer band */
+}
+.grid-card .card-section-title {
+ color: var(--ry-text);
+ font-size: 16px !important;
+ font-weight: 500 !important;
+}
+.scene-card__date,
+.performer-card__age {
+ color: var(--ry-text-3) !important;
+ font-size: 13px;
+}
+.scene-card__details {
+ margin-bottom: 0 !important;
+}
+.scene-card__description,
+.TruncatedText.scene-card__description {
+ color: var(--ry-text-2);
+ font-size: 13px;
+}
+.grid-card .card-popovers {
+ margin: auto 0 0 !important;
+ padding: 10px 14px !important;
+ background-color: rgba(255, 255, 255, 0.03);
+ border-top: 1px solid var(--ry-line);
+ justify-content: center !important;
+ gap: 24px;
+}
+.grid-card hr {
+ display: none;
+}
+.grid-card .card-popovers .btn {
+ color: var(--ry-text);
+ border: 0 !important;
+ background: none !important;
+ box-shadow: none !important;
+ padding: 0 !important;
+}
+.grid-card .card-popovers .btn:hover {
+ color: var(--ry-yellow-text);
+}
+.scene-card .scene-specs-overlay {
+ font-size: 12px !important;
+ font-weight: 700;
color: #fff;
- text-align: center;
- white-space: nowrap;
- background-color: var(--btnaccentcol);
- transition: width 0.6s ease;
+}
+.scene-card .scene-specs-overlay span {
+ margin: 0 !important;
+ padding: 0 !important;
+}
+.scene-card .scene-specs-overlay .overlay-resolution + .overlay-duration::before {
+ content: "\00a0";
+}
+.scene-card .extra-scene-info,
+.scene-card .overlay-filesize {
+ display: none !important;
+}
+/* Rating ribbon off the cards; the rating stays on the scene page */
+.grid-card .rating-banner {
+ display: none;
+}
+.performer-card .performer-card-image {
+ width: 100% !important;
+ height: auto !important;
+ min-width: 0 !important;
+ max-width: none !important;
+ max-height: none !important;
+ aspect-ratio: 2 / 3;
+ object-fit: cover;
+ object-position: top;
+}
+.studio-card .studio-card-header,
+.tag-card .tag-card-header {
+ display: block !important;
+ position: relative;
+ aspect-ratio: 16 / 9;
+ height: auto !important;
+}
+.studio-card .studio-card-image,
+.tag-card .tag-card-image {
+ position: absolute;
+ inset: 0;
+ width: 100% !important;
+ height: 100% !important;
+ max-height: none !important;
+ object-fit: contain;
+ padding: 10% 12%;
}
-.grid-card .progress-bar {
- background-color: rgba(115, 133, 159, 0.5);
- bottom: 5px;
+/* Studio chip top-left on the cover */
+.scene-card .studio-overlay {
+ top: 8px !important;
+ left: 8px !important;
+ right: auto !important;
+ max-width: 60%;
+ height: auto !important;
+ padding: 3px 7px;
+ border-radius: var(--ry-radius-sm);
+ background-color: rgba(0, 0, 0, 0.55);
+ opacity: 1;
+ line-height: 0;
+}
+.scene-card .studio-overlay a {
display: block;
- height: 5px;
- position: absolute;
- width: 100%;
+ height: auto !important;
+}
+.scene-card .studio-overlay .image-thumbnail {
+ height: 18px !important;
+ max-height: 18px !important;
+ width: auto;
+ max-width: 100% !important;
+ object-fit: contain;
}
-.grid-card .progress-indicator {
- background-color: var(--btnaccentcol);
- height: 5px;
+/* Card heart: the same size as the select checkbox, mirrored in the
+ opposite corner */
+.grid-card .favorite-button {
+ top: 10px !important;
+ right: 8px !important;
+ padding: 0 !important;
+ line-height: 1;
+}
+.grid-card .favorite-button svg {
+ width: 17px !important;
+ height: 17px !important;
+ font-size: 17px !important;
+ margin: 0 !important;
+}
+
+/* Home carousels: slides pulled in so the arrows sit inside the page (stock
+ pushes the next arrow off a phone screen), arrows centred on the cards (not
+ the cards plus the dots below), every card in a row as tall as the tallest */
+.recommendation-row .slick-slider {
+ margin: 0 30px;
+}
+.recommendation-row .slick-prev {
+ left: -28px;
+}
+.recommendation-row .slick-next {
+ right: -28px;
+}
+.recommendation-row .slick-slider {
+ margin-bottom: 30px;
+}
+.recommendation-row .slick-dots {
+ position: absolute; /* out of the flow, so the slider is exactly the cards' height */
+ top: 100%;
+}
+.recommendation-row .slick-track {
+ margin-bottom: 0;
+}
+.recommendation-row .slick-arrow {
+ top: 0;
+ height: 100%;
+ transform: none;
+ color: var(--ry-yellow-text);
+}
+.recommendation-row .slick-track {
+ display: flex !important;
+}
+.recommendation-row .slick-slide {
+ height: auto !important;
+}
+.recommendation-row .slick-slide > div {
+ height: 100%;
+}
+.recommendation-row .slick-slide .grid-card {
+ width: 320px !important; /* studios too, not just scenes and performers */
+ height: calc(100% - 10px);
+ margin-top: 5px;
+ margin-bottom: 5px;
}
-.hover-scrubber .hover-scrubber-indicator .hover-scrubber-indicator-marker {
- background-color: var(--btnaccentcol);
- bottom: 0;
- height: 5px;
+/* Detail pages: white titles, grey labels */
+.detail-header {
+ background-color: var(--ry-bg) !important;
+ border-bottom: 1px solid var(--ry-line);
+}
+/* Performer page: full-bleed portrait fading into the header */
+.detail-header:has(.performer-head) {
+ padding: 0 !important;
+ margin: 0 !important;
+ width: auto !important;
+ max-width: none !important;
+}
+.detail-header:has(.performer-head) .detail-container {
+ max-width: none;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ align-items: flex-start;
+}
+.detail-header:has(.performer-head) .detail-header-image {
+ position: relative;
+ flex: 0 0 420px;
+ width: 420px;
+ height: 400px;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+}
+.detail-header:has(.performer-head) .detail-header-image .btn-link {
+ display: block;
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ border: 0 !important;
+}
+.detail-header:has(.performer-head) img.performer {
+ width: 100%;
+ height: 100%;
+ max-width: none !important;
+ max-height: none;
+ object-fit: cover;
+ object-position: center top;
+ border: 0 !important;
+ border-radius: 0 !important;
+}
+.detail-header:has(.performer-head) .detail-header-image::after {
+ content: "";
position: absolute;
+ inset: 0;
+ pointer-events: none;
+ background: linear-gradient(90deg, transparent 55%, var(--ry-bg));
+}
+.detail-header:has(.performer-head) > .detail-container > .row {
+ flex: 1;
+ min-width: 0;
+ margin: 0;
+ padding: 24px 36px 0;
+}
+.detail-header:has(.performer-head) .performer-head .col,
+.detail-header:has(.performer-head) .performer-head .row {
+ padding: 0 !important;
+ margin: 0 !important;
+}
+.detail-header .detail-item {
+ font-size: 13px;
+ line-height: 1.4;
+ margin: 0 !important;
+ padding: 0 !important;
+}
+.detail-header .detail-group {
+ row-gap: 5px;
+}
+.detail-header .detail-item-title {
+ width: 130px;
+}
+@media (max-width: 767.98px) {
+ .detail-header:has(.performer-head) .detail-container {
+ flex-direction: column;
+ }
+ .detail-header:has(.performer-head) .detail-header-image {
+ flex-basis: auto;
+ width: 100%;
+ height: 430px;
+ }
+ .detail-header:has(.performer-head) .detail-header-image::after {
+ background: linear-gradient(180deg, transparent 55%, var(--ry-bg));
+ }
+ .detail-header:has(.performer-head) > .detail-container > .row {
+ padding: 14px;
+ }
+}
+.detail-header .performer-name,
+.detail-header .studio-name,
+.detail-header h2 {
+ color: var(--ry-text);
+ font-size: 40px;
+ font-weight: 500;
+}
+.detail-header .detail-item-title {
+ color: var(--ry-text-3);
+}
+.detail-header .detail-item-value {
+ color: var(--ry-text);
+}
+.details-edit {
+ gap: 8px;
+}
+.details-edit .btn {
+ margin: 0 !important;
+}
+.details-edit .btn-secondary {
+ color: var(--ry-text);
+ background-color: var(--ry-raised);
+ border-color: var(--ry-raised);
+}
+.details-edit .btn-primary,
+.details-edit .edit {
+ color: var(--ry-ink);
+ background-color: var(--ry-yellow);
+ border-color: var(--ry-yellow);
+}
+
+/* Scene page */
+.scene-tabs .scene-header,
+.scene-tabs .scene-header .TruncatedText {
+ color: var(--ry-text);
+ font-size: 32px !important;
+ font-weight: 500;
+ line-height: 1.15;
+}
+/* Scene details: white labels and headings, yellow links, grey paragraphs */
+.scene-tabs .tab-content h6 {
+ color: var(--ry-text);
+ font-size: 13px;
+}
+.scene-tabs .tab-content h6 a {
+ color: var(--ry-yellow-text);
+}
+.scene-tabs .tab-content p.pre {
+ color: var(--ry-text-2);
+ font-size: 13px;
+}
+.tag-item.badge-secondary {
+ color: var(--ry-text);
+ background-color: var(--ry-raised);
+ border: 1px solid var(--ry-line);
+}
+.nav-tabs .badge,
+.badge-pill.badge-secondary {
+ color: var(--ry-text);
+ background-color: var(--ry-raised);
+}
+.tag-item.badge-secondary a {
+ color: inherit;
+}
+.video-js .vjs-play-progress,
+.video-js .vjs-volume-level {
+ background-color: var(--ry-yellow);
+}
+.video-js .vjs-big-play-button {
+ width: 72px !important;
+ height: 72px !important;
+ margin-left: -36px !important;
+ margin-top: -36px !important;
+ font-size: 36px !important;
+ line-height: 72px !important;
+ border: 0 !important;
+ border-radius: 50% !important;
+ background-color: rgba(40, 40, 40, 0.85) !important;
+}
+.video-js:hover .vjs-big-play-button {
+ color: var(--ry-ink) !important;
+ background-color: var(--ry-yellow) !important;
+}
+.video-js .vjs-big-play-button .vjs-icon-placeholder::before {
+ font-size: 36px !important;
+ line-height: 72px !important;
+ width: 100% !important;
+ height: 100% !important;
+ text-indent: 3px;
+}
+.scrubber-button {
+ color: var(--ry-yellow-text) !important;
+ background-color: var(--ry-card) !important;
+ border: 1px solid var(--ry-line) !important;
+}
+/* Two performers side by side in the details panel */
+.scene-performers .performer-card {
+ width: calc(50% - 10px) !important;
+ margin: 5px !important;
+}
+
+/* Settings: white headings, yellow toggles */
+#settings-container h1,
+#tasks-panel h1,
+.setting-section h1 {
+ color: var(--ry-text);
+ font-size: 28px;
+ font-weight: 500;
+}
+.setting-section .setting h3,
+.setting-section > h2 {
+ color: var(--ry-text);
+}
+.custom-switch .custom-control-input:checked ~ .custom-control-label::before {
+ background-color: var(--ry-yellow);
+ border-color: var(--ry-yellow);
}
+/* Dialogs and menus on the card tone */
+.modal-content,
+.dropdown-menu {
+ background-color: var(--ry-card);
+ border: 1px solid var(--ry-line);
+ border-radius: var(--ry-radius-card);
+}
+.dropdown-menu {
+ padding: 6px;
+ box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
+}
+.dropdown-item {
+ border-radius: var(--ry-radius);
+}
+.modal-header {
+ border-bottom: 1px solid var(--ry-line);
+ color: var(--ry-text);
+}
+.modal-footer {
+ border-top: 1px solid var(--ry-line);
+}
+.modal-footer .btn-primary {
+ color: var(--ry-ink);
+ background-color: var(--ry-yellow);
+ border-color: var(--ry-yellow);
+}
+.dropdown-item {
+ color: var(--ry-text);
+}
+.dropdown-item:hover,
+.dropdown-item.active {
+ color: var(--ry-text);
+ background-color: var(--ry-raised);
+}
+
+/* Theme Switch menu: its sections are spaced apart, so keep the full outline
+ that Bootstrap's accordion style strips from all but the last */
+.theme-plugin-menu .accordion > .card {
+ border-bottom: 1px solid var(--ry-line) !important;
+ border-radius: var(--ry-radius) !important;
+}
+
+/* Empty lists */
+.item-list-container .sidebar-pane-content:not(:has(.grid-card, .table-list, .scene-wall, .wall, .tagger-container, .card)) > .pagination-index-container::after {
+ content: "Nothing here yet";
+ grid-column: 1 / -1;
+ margin-top: 18vh;
+ text-align: center;
+ font-size: 26px;
+ font-weight: 500;
+ color: var(--ry-text-2);
+}
+
+/* Task queue and job cards: off the stock blue-grey */
#tasks-panel .tasks-panel-queue {
- background-color: var(--bgcol);
- margin-top: -1rem;
- padding-bottom: 0.25rem;
- padding-top: 1rem;
- position: sticky;
- top: 3rem;
- z-index: 2;
+ background-color: var(--ry-bg) !important;
+}
+.job-table.card {
+ background-color: var(--ry-card) !important;
+ border: 1px solid var(--ry-line);
+}
+/* Settings buttons are secondary; the scene-page panel toggle keeps the theme */
+#settings-container .btn-primary {
+ color: var(--ry-text);
+ background-color: var(--ry-raised);
+ border-color: var(--ry-raised);
+}
+.scene-divider .btn {
+ color: var(--ry-text-2);
+ background: none;
+ border: 0;
}
-#scene-edit-details .edit-buttons-container {
- background-color: var(--bgcol);
- position: sticky;
- top: 0;
- z-index: 3;
+/* Home carousels: whole cards only. The number of cards that fits at about
+ 320px, sized to fill the row exactly, so none is cut off at the edge */
+.recommendation-row .slick-list {
+ container-type: inline-size;
+}
+.recommendation-row .slick-slide .grid-card {
+ width: calc(100cqw / max(1, round(100cqw / 330px, 1)) - 10px) !important;
+ max-width: none !important;
+}
+
+/* Detail-page tab bars: Stash pads them below, which lifts the active
+ underline off the bar's line */
+.nav-tabs {
+ padding-bottom: 0 !important;
+}
+
+/* The slim header Stash pins when a detail page scrolls slides down only as
+ the full header's bottom edge passes under the top bar, instead of
+ appearing as soon as the page moves. It follows the scroll position, so
+ scrolling back up reverses it; browsers without scroll-driven animations
+ show it as Stash does. */
+@supports (animation-timeline: view()) {
+ .main {
+ timeline-scope: --detail-header;
+ }
+ .detail-header:not(.sticky) {
+ view-timeline: --detail-header block;
+ }
+ .detail-header.sticky {
+ animation: detail-header-sticky-in linear both;
+ animation-timeline: --detail-header;
+ animation-range: exit calc(100% - 130px) exit calc(100% - 50px);
+ }
+ @keyframes detail-header-sticky-in {
+ from {
+ transform: translateY(-100%);
+ opacity: 0;
+ visibility: hidden;
+ }
+ to {
+ transform: none;
+ opacity: 1;
+ visibility: visible;
+ }
+ }
+}
+
+/* Filter sidebar on small screens. Stash slides it over the page below 768px,
+ covering the button that closes it. Phones get a full-screen sheet whose
+ "Show N results" button is the way out; small tablets get the desktop
+ layout, the content pushed aside to a single column. */
+@media (max-width: 575.98px) {
+ .sidebar-pane:not(.hide-sidebar) {
+ z-index: 1020; /* above the performer header, which is its own layer */
+ }
+ .sidebar-pane:not(.hide-sidebar) > .sidebar {
+ position: fixed !important;
+ top: 0 !important;
+ left: 0 !important;
+ right: 0 !important;
+ bottom: auto !important;
+ width: 100% !important;
+ max-width: none !important;
+ height: calc(100dvh - 46px) !important; /* down to the bottom bar */
+ max-height: none !important;
+ flex: none !important;
+ margin: 0 !important;
+ padding: 12px 15px 0 !important;
+ display: flex !important;
+ flex-direction: column;
+ z-index: 1020;
+ background-color: var(--ry-bar) !important;
+ }
+ .sidebar-pane:not(.hide-sidebar) > .sidebar .sidebar-footer {
+ margin-top: auto;
+ bottom: 0;
+ left: 0 !important;
+ width: 100% !important;
+ padding: 12px 0 15px !important;
+ background: none !important;
+ border-top: 0 !important;
+ }
+ .sidebar-pane:not(.hide-sidebar) > .sidebar .sidebar-footer .btn {
+ width: 100%;
+ height: 44px;
+ }
+}
+@media (min-width: 576px) and (max-width: 767.98px) {
+ .sidebar-pane:not(.hide-sidebar) > .sidebar-pane-content {
+ margin-left: 235px;
+ }
+ .sidebar-pane:not(.hide-sidebar) .sidebar-toggle-button-container {
+ left: 257px;
+ }
+ .sidebar-pane:not(.hide-sidebar) .grid-card {
+ width: calc(100% - 30px) !important; /* one column beside the filters */
+ }
+}
+
+/* Detail fields on phones: the label above its value, so long values like a
+ Stash ID get the full width; an ID that still doesn't fit ends in an
+ ellipsis (the link opens the full ID) */
+@media (max-width: 575.98px) {
+ .detail-header .detail-item {
+ display: block !important;
+ }
+ .detail-header .detail-item-title {
+ display: block;
+ width: auto !important;
+ margin-bottom: 1px;
+ }
+ .detail-header > .detail-container > .row {
+ align-self: stretch;
+ max-width: 100%;
+ }
+ .detail-header .performer-head,
+ .detail-header .detail-group {
+ min-width: 0;
+ max-width: 100%;
+ }
+}
+.stash-id-pill {
+ display: inline-flex !important;
+ max-width: 100%;
+ min-width: 0;
+}
+.stash-id-pill span {
+ flex: none;
+}
+.stash-id-pill a {
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.detail-item-value.stash-ids,
+.detail-item-value.stash-ids ul,
+.detail-item-value.stash-ids li {
+ display: block;
+ max-width: 100%;
+ min-width: 0;
+ margin: 0;
+}
+.detail-item-value.stash-ids {
+ overflow: hidden;
+}
+
+/* Dialog panels on the dialog's own colour, not Stash's slate */
+.modal-content {
+ background-color: var(--ry-card) !important;
+}
+.modal-header,
+.modal-body,
+.modal-footer {
+ background: transparent !important;
+}
+
+/* Phones: dialogs (Edit filter and the rest) fill the screen down to the
+ bottom bar; the body scrolls and the buttons stay at the foot */
+@media (max-width: 575.98px) {
+ .modal-dialog {
+ max-width: none !important;
+ width: 100% !important;
+ margin: 0 !important;
+ height: calc(100dvh - 46px);
+ }
+ .modal-content {
+ height: 100%;
+ border-radius: 0 !important;
+ border: 0 !important;
+ background-color: var(--ry-card) !important;
+ }
+ .modal-body {
+ flex: 1;
+ max-height: none !important; /* Stash caps it at a fixed height */
+ overflow-y: auto;
+ }
+ .modal-footer {
+ flex-wrap: nowrap;
+ }
+}
+
+/* Phone and tablet menu (the ☰ button): an even grid of tiles, small icon
+ above its label, the current page on a soft tile, utility icons in a row
+ beneath a hairline (stock crams large icons beside the words) */
+@media (max-width: 1199.98px) {
+ .navbar-collapse.show,
+ .navbar-collapse.collapsing {
+ background-color: var(--ry-bar) !important;
+ border-top: 1px solid var(--ry-line);
+ padding: 10px 24px 6px !important;
+ margin: 0 -14px; /* edge to edge across the bar's padding */
+ }
+ .navbar-collapse > .navbar-nav:first-child {
+ display: grid !important;
+ grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); /* 3 across on phones */
+ gap: 6px;
+ }
+ .navbar-collapse > .navbar-nav:first-child > div {
+ max-width: none !important;
+ flex: none !important;
+ width: auto !important;
+ padding: 0 !important;
+ }
+ .navbar-collapse > .navbar-nav > div > a {
+ display: flex !important;
+ flex-direction: column !important;
+ align-items: center !important;
+ justify-content: center !important;
+ gap: 6px;
+ height: 64px !important;
+ padding: 6px !important;
+ color: var(--ry-text) !important;
+ background: none !important;
+ border: 0 !important;
+ border-radius: 8px !important;
+ box-shadow: none !important;
+ font-size: 12px;
+ font-weight: 600;
+ text-transform: none;
+ }
+ .navbar-collapse > .navbar-nav > div > a svg {
+ display: block !important;
+ width: 20px !important;
+ height: 20px !important;
+ font-size: 20px !important;
+ margin: 0 !important;
+ color: var(--ry-text-2);
+ }
+ .navbar-collapse > .navbar-nav > div > a.active {
+ color: var(--ry-yellow-text) !important;
+ background-color: var(--ry-raised) !important;
+ }
+ .navbar-collapse > .navbar-nav > div > a.active svg {
+ color: var(--ry-yellow-text);
+ }
+ .navbar-collapse > .navbar-nav:not(:first-child) {
+ justify-content: center;
+ gap: 8px;
+ margin-top: 8px;
+ padding-top: 6px;
+ border-top: 1px solid var(--ry-line);
+ }
+ .navbar-collapse .nav-utility svg {
+ width: 18px !important;
+ height: 18px !important;
+ }
+}
+
+/* Phones: the list toolbar on two rows. The space for the filter button is
+ kept on the first row only (search stretches beside it, then the
+ saved-filter and filter buttons); the rest slims down to share row two. */
+@media (max-width: 575.98px) {
+ .filtered-list-toolbar {
+ margin-left: 0 !important;
+ margin-right: 0 !important; /* stock keeps 40px each side */
+ justify-content: flex-start !important;
+ gap: 8px 6px !important;
+ }
+ .filtered-list-toolbar > .search-term-input {
+ margin-left: 40px !important;
+ flex: 1 1 0 !important;
+ min-width: 0 !important;
+ width: auto !important;
+ }
+ .filtered-list-toolbar > .search-term-input .form-control {
+ width: 100% !important;
+ min-width: 0 !important;
+ }
+ .filtered-list-toolbar .sort-by-select .btn {
+ padding: 0 6px !important;
+ }
+ .filtered-list-toolbar > .page-size-selector,
+ .filtered-list-toolbar > .page-size-selector select {
+ width: 56px !important;
+ min-width: 0 !important;
+ }
+ .filtered-list-toolbar .btn-group:not(.pagination) .btn {
+ padding: 0 6px !important;
+ }
+ .filtered-list-toolbar > .btn-group:last-of-type {
+ margin-left: auto; /* the view buttons close the second row on the right */
+ }
+ /* row 1: search + the filter buttons; a zero-height break; row 2: the rest */
+ .filtered-list-toolbar > * {
+ order: 3;
+ }
+ .filtered-list-toolbar > .search-term-input,
+ .filtered-list-toolbar > .search-term-input + .btn-group {
+ order: 1;
+ }
+ .filtered-list-toolbar::after {
+ content: "";
+ order: 2;
+ flex-basis: 100%;
+ height: 0;
+ }
+}
+
+/* The phone menu button wears the same colour as the nav icons beside it */
+.top-nav .nav-menu-toggle,
+.top-nav .nav-menu-toggle:hover,
+.top-nav .nav-menu-toggle:focus {
+ color: var(--ry-text-2);
+}
+
+/* Theme Switch menu: solid, on the theme's menu colours (stock leaves its
+ sections on Bootstrap's slate, and see-through over the cards) */
+.theme-plugin-menu.dropdown-menu {
+ padding: 6px !important;
+ color: var(--ry-text);
+ background: var(--ry-card) !important;
+ border: 1px solid var(--ry-line) !important;
+ border-radius: var(--ry-radius-card) !important;
+ box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45) !important;
+}
+.theme-plugin-menu .accordion {
+ max-width: none !important;
+}
+.theme-plugin-menu .modal-header {
+ margin: 0 0 6px;
+ padding: 6px 8px 10px !important;
+ color: var(--ry-text) !important;
+ background: none !important;
+ border: 0 !important;
+ border-bottom: 1px solid var(--ry-line) !important;
+ border-radius: 0 !important;
+ font-size: 14px;
+ font-weight: 600;
+ text-shadow: none;
+}
+.theme-plugin-menu .accordion > .card {
+ margin: 0 0 4px !important;
+ color: var(--ry-text) !important;
+ background: rgba(255, 255, 255, 0.04) !important;
+ border: 1px solid var(--ry-line) !important;
+ border-radius: var(--ry-radius) !important;
+ box-shadow: none !important;
+ backdrop-filter: none !important;
+}
+.theme-plugin-menu .card-header,
+.theme-plugin-menu .card-body {
+ color: var(--ry-text) !important;
+ background: none !important;
+ border: 0 !important;
+ text-shadow: none;
+}
+.theme-plugin-menu .card-header {
+ cursor: pointer;
+}
+.theme-plugin-menu .card-header svg {
+ color: var(--ry-text-2);
+}
+.theme-plugin-menu legend {
+ color: var(--ry-text) !important;
+}
+.theme-plugin-menu .checkbox-switch input + label::before {
+ color: var(--ry-text-2) !important;
+ background: color-mix(in srgb, var(--ry-text-2) 30%, transparent) !important;
+ border-color: transparent !important;
+}
+.theme-plugin-menu .checkbox-switch input:checked + label::before {
+ color: #fff !important;
+ background: var(--ry-yellow) !important;
+ border-color: var(--ry-yellow) !important;
+}
+/* A blurred bar turns everything drawn inside it see-through, the open
+ menu included: while the menu is open the bar drops its blur */
+.top-nav:has(.theme-plugin-menu.show) {
+ backdrop-filter: none !important;
+ -webkit-backdrop-filter: none !important;
}
diff --git a/themes/Theme-RoundedYellow/Theme-RoundedYellow.yml b/themes/Theme-RoundedYellow/Theme-RoundedYellow.yml
index 660a84e3..48b347e9 100644
--- a/themes/Theme-RoundedYellow/Theme-RoundedYellow.yml
+++ b/themes/Theme-RoundedYellow/Theme-RoundedYellow.yml
@@ -1,6 +1,6 @@
name: Theme - Rounded Yellow
description: Theme with rounded corners and yellow accents
-version: 1.0
+version: 2.0
url: https://discourse.stashapp.cc/t/rounded-yellow/1431
ui:
css: