diff --git a/webui/index.html b/webui/index.html
index 42cc5cfe..a6b2311e 100644
--- a/webui/index.html
+++ b/webui/index.html
@@ -891,19 +891,19 @@
-
+
diff --git a/webui/static/video/video-discover.js b/webui/static/video/video-discover.js
index 858d0a2e..ade62b01 100644
--- a/webui/static/video/video-discover.js
+++ b/webui/static/video/video-discover.js
@@ -48,6 +48,18 @@
];
var GENRE_RAILS = ['Action', 'Adventure', 'Comedy', 'Drama', 'Science Fiction',
'Thriller', 'Horror', 'Animation', 'Fantasy', 'Romance', 'Documentary', 'Crime'];
+ // A thematic colour per genre so the chips read intentional, not random.
+ var GENRE_COLORS = {
+ 'action': '239, 68, 68', 'adventure': '34, 197, 94', 'animation': '168, 85, 247',
+ 'comedy': '245, 197, 24', 'crime': '120, 113, 108', 'documentary': '20, 184, 166',
+ 'drama': '96, 165, 250', 'family': '74, 222, 128', 'fantasy': '192, 132, 252',
+ 'history': '202, 138, 4', 'horror': '220, 38, 38', 'music': '236, 72, 153',
+ 'mystery': '99, 102, 241', 'romance': '244, 114, 182', 'science fiction': '34, 211, 238',
+ 'sci-fi & fantasy': '34, 211, 238', 'tv movie': '148, 163, 184', 'thriller': '100, 116, 139',
+ 'war': '161, 98, 7', 'war & politics': '161, 98, 7', 'western': '180, 130, 80',
+ 'kids': '74, 222, 128', 'reality': '251, 146, 60', 'soap': '244, 114, 182',
+ 'talk': '148, 163, 184', 'news': '148, 163, 184',
+ };
var DECADE_RAILS = [
{ title: 'Best of the 2010s', q: 'kind=movie&decade=2010&sort=vote_average.desc' },
{ title: '2000s Favorites', q: 'kind=movie&decade=2000&sort=vote_average.desc' },
@@ -366,9 +378,11 @@
}
function renderGenreChips() {
var box = $('[data-vdsc-chipset="genre"]'); if (!box) return;
- box.innerHTML = '' +
+ box.innerHTML = '' +
(state.genres[state.sel.kind] || []).map(function (g) {
- return '';
+ var c = GENRE_COLORS[(g.name || '').toLowerCase()];
+ return '';
}).join('');
state.sel.genre = '';
}
diff --git a/webui/static/video/video-side.css b/webui/static/video/video-side.css
index 9dd79eab..7dd27e15 100644
--- a/webui/static/video/video-side.css
+++ b/webui/static/video/video-side.css
@@ -2273,9 +2273,7 @@ body[data-side="video"] #soulsync-toggle { display: none; }
.vdsc-toggle input { accent-color: rgb(var(--accent-rgb, 88 101 242)); width: 16px; height: 16px; cursor: pointer; }
.vdsc-hide-owned .vsr-card--owned { display: none; }
-/* rails: soft edge fade + a gentle fade-in when filled + per-title hue on hover */
-.vdsc-rail { -webkit-mask-image: linear-gradient(90deg, transparent, #000 18px, #000 calc(100% - 18px), transparent);
- mask-image: linear-gradient(90deg, transparent, #000 18px, #000 calc(100% - 18px), transparent); }
+/* rails: a gentle fade-in when filled + per-title hue on hover */
.vdsc-shelf--in .vdsc-rail { animation: vdscFade 0.45s ease both; }
@keyframes vdscFade { from { opacity: 0.35; } to { opacity: 1; } }
.vdsc-rail .vsr-card, .vdsc-grid .vsr-card { transition: transform 0.2s ease, box-shadow 0.2s ease; }
@@ -2298,11 +2296,9 @@ body[data-side="video"] #soulsync-toggle { display: none; }
.vdsc-seg { display: inline-flex; gap: 6px; }
.vdsc-seg::before { display: none; }
-/* chip rows (genres, providers, eras) — horizontally scrollable, edge-faded */
+/* chip rows (genres, providers, eras) — horizontally scrollable */
.vdsc-chips { display: flex; gap: 8px; overflow-x: auto; padding: 4px 1px 7px; margin-top: 13px;
- scrollbar-width: thin;
- -webkit-mask-image: linear-gradient(90deg, transparent, #000 14px, #000 calc(100% - 14px), transparent);
- mask-image: linear-gradient(90deg, transparent, #000 14px, #000 calc(100% - 14px), transparent); }
+ scrollbar-width: thin; }
.vdsc-chips::-webkit-scrollbar { height: 6px; }
.vdsc-chips::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.13); border-radius: 3px; }
.vdsc-chips--era { margin-top: 0; }
@@ -2322,16 +2318,16 @@ body[data-side="video"] #soulsync-toggle { display: none; }
box-shadow: 0 9px 22px -9px rgba(var(--c, 120, 130, 240), 0.9),
0 0 0 1px rgba(var(--c, 120, 130, 240), 0.42), inset 0 1px 0 rgba(255, 255, 255, 0.25); }
-/* the palette — cycles across each row so a filter row reads colorful
- (comma-separated triples so they slot into rgba(var(--c), a)) */
-.vdsc-chip:nth-child(8n+1), .vdsc-seg-btn:nth-child(8n+1) { --c: 29, 185, 84; } /* green */
-.vdsc-chip:nth-child(8n+2), .vdsc-seg-btn:nth-child(8n+2) { --c: 147, 112, 219; } /* purple */
-.vdsc-chip:nth-child(8n+3), .vdsc-seg-btn:nth-child(8n+3) { --c: 100, 149, 237; } /* blue */
-.vdsc-chip:nth-child(8n+4), .vdsc-seg-btn:nth-child(8n+4) { --c: 245, 158, 11; } /* amber */
-.vdsc-chip:nth-child(8n+5), .vdsc-seg-btn:nth-child(8n+5) { --c: 236, 72, 153; } /* pink */
-.vdsc-chip:nth-child(8n+6), .vdsc-seg-btn:nth-child(8n+6) { --c: 34, 211, 238; } /* cyan */
-.vdsc-chip:nth-child(8n+7), .vdsc-seg-btn:nth-child(8n+7) { --c: 248, 113, 113; } /* coral */
-.vdsc-chip:nth-child(8n), .vdsc-seg-btn:nth-child(8n) { --c: 168, 85, 247; } /* violet */
+/* Colours carry meaning, not position:
+ - segments (Movies/TV, sort) → the app accent (they're modes, not categories)
+ - genre chips → a thematic colour per genre (set inline by JS)
+ - provider chips → the service's brand colour (set inline in markup)
+ - era chips → a single warm amber; reset chips ('All/Any …') → neutral
+ so each --c is provided where it's meaningful and falls back to neutral here. */
+.vdsc-seg-btn { --c: var(--accent-rgb, 29, 185, 84); }
+.vdsc-chip--reset { --c: 148, 163, 184; } /* All genres / Any service / Any era */
+.vdsc-chips--era .vdsc-chip { --c: 245, 158, 11; }
+.vdsc-chips--era .vdsc-chip--reset { --c: 148, 163, 184; }
.vdsc-browse-bottom { display: flex; align-items: center; gap: 16px; margin-top: 12px; }
.vdsc-browse-bottom .vdsc-chips { flex: 1; min-width: 0; margin-top: 0; }