diff --git a/src/renderer-profile.ts b/src/renderer-profile.ts
index 1beed83..38ec6a0 100644
--- a/src/renderer-profile.ts
+++ b/src/renderer-profile.ts
@@ -111,8 +111,10 @@ function renderStreamerProfileCard(p: StreamerProfile): void {
`;
// Banner-as-background — set inline so the URL stays per-streamer.
+ // The darkening gradient is handled by the .streamer-profile-header::before
+ // pseudo so the banner itself stays bright and unfiltered here.
const bannerStyle = p.bannerUrl
- ? `background-image: linear-gradient(135deg, rgba(14,14,16,0.78) 0%, rgba(14,14,16,0.92) 100%), url("${p.bannerUrl.replace(/"/g, '%22')}");`
+ ? `background-image: url("${p.bannerUrl.replace(/"/g, '%22')}");`
: '';
// Live preview block — only when currently live. Big card with
diff --git a/src/styles.css b/src/styles.css
index 4793276..8ca9172 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -978,6 +978,139 @@ body {
cursor: pointer;
}
+/* ============================================
+ COMPACT / UTILITY BUTTONS
+ ============================================
+ .btn-pill — small action buttons used in toolbars + bulk-bars.
+ Comes in default (transparent), primary (purple), success (green).
+ Replaces the inline-style blocks the renderer was rolling for each
+ bulk action button. */
+.btn-pill {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+ background: transparent;
+ color: var(--text-secondary);
+ border: 1px solid var(--border-soft);
+ border-radius: 6px;
+ padding: 6px 12px;
+ font-size: 13px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.15s;
+ line-height: 1.2;
+}
+
+.btn-pill:hover:not(:disabled) {
+ background: rgba(255, 255, 255, 0.06);
+ color: var(--text);
+ border-color: rgba(255, 255, 255, 0.18);
+}
+
+.btn-pill:active:not(:disabled) {
+ transform: translateY(1px);
+}
+
+.btn-pill:disabled {
+ opacity: 0.45;
+ cursor: not-allowed;
+}
+
+.btn-pill.primary {
+ background: var(--accent);
+ color: #fff;
+ border-color: var(--accent);
+ font-weight: 600;
+}
+
+.btn-pill.primary:hover:not(:disabled) {
+ background: var(--accent-hover);
+ border-color: var(--accent-hover);
+ color: #fff;
+ box-shadow: 0 4px 14px rgba(145, 70, 255, 0.35);
+}
+
+.btn-pill.success {
+ background: #00c853;
+ color: #fff;
+ border-color: #00c853;
+ font-weight: 600;
+}
+
+.btn-pill.success:hover:not(:disabled) {
+ background: #00e676;
+ border-color: #00e676;
+ box-shadow: 0 4px 14px rgba(0, 200, 83, 0.35);
+}
+
+.btn-pill.danger {
+ background: transparent;
+ color: #ff6b6b;
+ border-color: rgba(255, 107, 107, 0.4);
+}
+
+.btn-pill.danger:hover:not(:disabled) {
+ background: rgba(255, 107, 107, 0.12);
+ border-color: rgba(255, 107, 107, 0.7);
+ color: #ff8a8a;
+}
+
+/* .btn-icon — square X-close button for filter clears, inline removals.
+ 1.6em wide, transparent base, hover only colours the X. */
+.btn-icon {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ background: transparent;
+ border: 1px solid var(--border-soft);
+ border-radius: 6px;
+ padding: 6px 10px;
+ color: var(--text-secondary);
+ cursor: pointer;
+ font-size: 12px;
+ font-weight: 500;
+ transition: background 0.15s, color 0.15s, border-color 0.15s;
+ line-height: 1;
+}
+
+.btn-icon:hover:not(:disabled) {
+ background: rgba(255, 70, 70, 0.10);
+ border-color: rgba(255, 70, 70, 0.45);
+ color: #ff6b6b;
+}
+
+/* .queue-detail-btn — tiny chip-style action button used in queue item
+ detail rows AND in the archive search results list. Was previously
+ rendering with browser defaults (gray flat button). */
+.queue-detail-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ background: rgba(145, 70, 255, 0.10);
+ color: var(--text);
+ border: 1px solid rgba(145, 70, 255, 0.30);
+ border-radius: 5px;
+ padding: 4px 10px;
+ margin-right: 6px;
+ margin-bottom: 4px;
+ font-size: 11px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.12s;
+}
+
+.queue-detail-btn:hover {
+ background: rgba(145, 70, 255, 0.22);
+ border-color: rgba(145, 70, 255, 0.6);
+ color: #fff;
+ transform: translateY(-1px);
+}
+
+.queue-detail-btn:active {
+ transform: translateY(0);
+}
+
/* Clips */
.clip-input {
max-width: 600px;
@@ -1949,23 +2082,35 @@ body.theme-light .modal {
for instant familiarity, but trimmed for the desktop-app context. */
.streamer-profile-header {
position: sticky;
- top: 0;
- z-index: 20;
+ top: -25px; /* negate the .content top padding so the header pins flush with the visible top edge */
+ z-index: 100;
display: block;
padding: 0;
+ margin-top: -2px;
margin-bottom: 14px;
- background: linear-gradient(135deg, rgba(145, 70, 255, 0.10) 0%, rgba(0, 200, 83, 0.04) 100%), var(--bg-card);
+ background: var(--bg-card);
border: 1px solid var(--border-soft);
border-radius: 12px;
overflow: hidden;
animation: profile-fade-in 0.32s ease-out;
- backdrop-filter: blur(6px);
- -webkit-backdrop-filter: blur(6px);
+ isolation: isolate; /* new stacking context so VODs below cannot leak above */
+ box-shadow: 0 6px 22px rgba(0, 0, 0, 0.35);
+}
+
+/* Dimming gradient sits ABOVE the banner-bg but BELOW the content row.
+ Gives the banner room to breathe while keeping name + bio readable. */
+.streamer-profile-header::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ background: linear-gradient(135deg, rgba(15, 15, 18, 0.55) 0%, rgba(15, 15, 18, 0.78) 100%);
+ z-index: 1;
+ pointer-events: none;
}
.streamer-profile-row {
position: relative;
- z-index: 1;
+ z-index: 2;
display: flex;
gap: 18px;
align-items: center;
@@ -1977,11 +2122,11 @@ body.theme-light .modal {
inset: 0;
background-size: cover;
background-position: center;
- filter: blur(18px) saturate(1.2);
- opacity: 0.55;
+ filter: blur(10px) saturate(1.35);
+ opacity: 1;
pointer-events: none;
z-index: 0;
- transform: scale(1.1); /* avoid the blur edge bleed */
+ transform: scale(1.12); /* hide the blur edge bleed inside the rounded corner clip */
}
@keyframes profile-fade-in {