feat: Discord-style glass morphism UI redesign + nightly CI/CD

- App shell: gradient title, glass admin modal, avatar, admin login/logout
- All plugin empty states: floating icon animations, updated typography
- Soundboard: orange accent theme replacing blurple default
- Global styles: glass morphism variables, Discord-dark color palette
- CI/CD: nightly deploy (stops main, starts nightly on port 8085) + manual restore-main job

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Daniel 2026-03-09 02:12:02 +01:00
parent ecd5e96ee2
commit 8abe0775a5
8 changed files with 556 additions and 94 deletions

View file

@ -472,24 +472,30 @@
/* ── Empty state ── */
.gl-empty {
text-align: center;
padding: 60px 20px;
flex: 1; display: flex; flex-direction: column;
align-items: center; justify-content: center; gap: 16px;
padding: 40px; height: 100%;
}
.gl-empty-icon {
font-size: 48px;
margin-bottom: 16px;
font-size: 64px; line-height: 1;
filter: drop-shadow(0 0 20px rgba(230,126,34,0.5));
animation: gl-empty-float 3s ease-in-out infinite;
}
@keyframes gl-empty-float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
.gl-empty h3 {
color: var(--text-normal);
margin: 0 0 8px;
font-size: 26px; font-weight: 700; color: #f2f3f5;
letter-spacing: -0.5px; margin: 0;
}
.gl-empty p {
color: var(--text-faint);
margin: 0;
font-size: 14px;
font-size: 15px; color: #80848e;
text-align: center; max-width: 360px; line-height: 1.5; margin: 0;
}
/* ── Common game playtime chips ── */

View file

@ -456,22 +456,26 @@
}
.lol-empty {
text-align: center;
padding: 60px 20px;
color: var(--text-faint);
flex: 1; display: flex; flex-direction: column;
align-items: center; justify-content: center; gap: 16px;
padding: 40px; height: 100%;
}
.lol-empty-icon {
font-size: 48px;
margin-bottom: 12px;
font-size: 64px; line-height: 1;
filter: drop-shadow(0 0 20px rgba(230,126,34,0.5));
animation: lol-float 3s ease-in-out infinite;
}
@keyframes lol-float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
.lol-empty h3 {
margin: 0 0 8px;
color: var(--text-muted);
font-size: 16px;
font-size: 26px; font-weight: 700; color: #f2f3f5;
letter-spacing: -0.5px; margin: 0;
}
.lol-empty p {
margin: 0;
font-size: 13px;
font-size: 15px; color: #80848e;
text-align: center; max-width: 360px; line-height: 1.5; margin: 0;
}
/* ── Load more ── */

View file

@ -3,7 +3,7 @@
/* Soundboard Plugin — ported from Jukebox styles */
/*
Theme Variables Default (Discord Blurple)
Theme Variables Default (Orange Accent)
*/
.sb-app {
--bg-deep: #1a1b1e;
@ -18,10 +18,10 @@
--text-muted: #949ba4;
--text-faint: #6d6f78;
--accent: #5865f2;
--accent-rgb: 88, 101, 242;
--accent-hover: #4752c4;
--accent-glow: rgba(88, 101, 242, .45);
--accent: #e67e22;
--accent-rgb: 230, 126, 34;
--accent-hover: #d35400;
--accent-glow: rgba(230, 126, 34, .45);
--green: #23a55a;
--red: #f23f42;
@ -91,6 +91,18 @@
--accent-glow: rgba(52, 152, 219, .4);
}
/* ── Theme: Cherry ── */
.sb-app[data-theme="cherry"] {
--bg-deep: #1a0f14;
--bg-primary: #221419;
--bg-secondary: #2f1c22;
--bg-tertiary: #3d242c;
--accent: #e74c3c;
--accent-rgb: 231, 76, 60;
--accent-hover: #c0392b;
--accent-glow: rgba(231, 76, 60, .4);
}
/*
App Layout
*/
@ -310,6 +322,33 @@
margin-left: 2px;
}
/* ── Disconnect Button ── */
.disconnect-btn {
display: flex;
align-items: center;
gap: 5px;
padding: 4px 10px;
border-radius: 20px;
background: rgba(242, 63, 66, .1);
border: 1px solid rgba(242, 63, 66, .2);
backdrop-filter: blur(8px);
color: var(--red);
font-size: 12px;
font-weight: 600;
cursor: pointer;
transition: all var(--transition);
}
.disconnect-btn:hover {
background: rgba(242, 63, 66, .2);
border-color: rgba(242, 63, 66, .4);
box-shadow: 0 0 12px rgba(242, 63, 66, .15);
}
.disconnect-btn:active {
transform: scale(0.97);
}
/* ── Connection Details Modal ── */
.conn-modal-overlay {
position: fixed;
@ -340,9 +379,10 @@
align-items: center;
gap: 8px;
padding: 14px 16px;
border-bottom: 1px solid var(--border);
font-weight: 700;
border-bottom: 1px solid rgba(255,255,255,.06);
font-size: 14px;
font-weight: 700;
color: var(--text-normal);
}
.conn-modal-close {
margin-left: auto;
@ -438,7 +478,9 @@
gap: 6px;
padding: 6px 14px;
border-radius: 20px;
background: var(--bg-tertiary);
background: rgba(255, 255, 255, .05);
border: 1px solid rgba(255, 255, 255, .08);
backdrop-filter: blur(8px);
color: var(--text-muted);
font-family: var(--font);
font-size: 13px;
@ -449,13 +491,16 @@
}
.cat-tab:hover {
background: var(--bg-modifier-selected);
background: rgba(255, 255, 255, .1);
border-color: rgba(255, 255, 255, .15);
color: var(--text-normal);
}
.cat-tab.active {
background: var(--accent);
color: var(--white);
border-color: var(--accent);
box-shadow: 0 2px 12px rgba(var(--accent-rgb), .35);
}
.tab-count {
@ -489,9 +534,9 @@
width: 100%;
height: 32px;
padding: 0 28px 0 32px;
border: 1px solid rgba(255, 255, 255, .06);
border: 1px solid rgba(255, 255, 255, .08);
border-radius: 20px;
background: var(--bg-secondary);
background: var(--bg-deep);
color: var(--text-normal);
font-family: var(--font);
font-size: 13px;
@ -572,8 +617,8 @@
height: 24px;
padding: 0 10px;
border-radius: 14px;
border: 1px solid rgba(var(--accent-rgb, 88, 101, 242), .45);
background: rgba(var(--accent-rgb, 88, 101, 242), .12);
border: 1px solid rgba(var(--accent-rgb), .45);
background: rgba(var(--accent-rgb), .12);
color: var(--accent);
font-size: 11px;
font-weight: 700;
@ -639,7 +684,7 @@
}
.tb-btn.random {
border-color: rgba(88, 101, 242, .3);
border-color: rgba(230, 126, 34, .3);
color: var(--accent);
}
@ -834,7 +879,7 @@
gap: 4px;
padding: 3px 8px;
border-radius: 999px;
background: rgba(var(--accent-rgb, 88, 101, 242), .15);
background: rgba(var(--accent-rgb), .15);
color: var(--accent);
font-size: 11px;
font-weight: 600;
@ -875,8 +920,9 @@
font-size: 12px;
font-weight: 600;
color: var(--text-muted);
background: var(--bg-secondary);
border: 1px solid rgba(255, 255, 255, .06);
background: rgba(255, 255, 255, .05);
border: 1px solid rgba(255, 255, 255, .08);
backdrop-filter: blur(8px);
white-space: nowrap;
cursor: pointer;
transition: all var(--transition);
@ -884,13 +930,16 @@
}
.cat-chip:hover {
border-color: rgba(255, 255, 255, .12);
border-color: rgba(255, 255, 255, .15);
color: var(--text-normal);
background: var(--bg-tertiary);
background: rgba(255, 255, 255, .1);
}
.cat-chip.active {
background: rgba(88, 101, 242, .1);
background: var(--accent);
color: var(--white);
border-color: var(--accent);
box-shadow: 0 2px 12px rgba(var(--accent-rgb), .35);
}
.cat-dot {
@ -924,7 +973,7 @@
}
/*
Sound Card
Sound Card Glass Morphism
*/
.sound-card {
position: relative;
@ -934,11 +983,13 @@
justify-content: center;
gap: 3px;
padding: 12px 6px 8px;
background: var(--bg-secondary);
background: rgba(255, 255, 255, .05);
border: 1px solid rgba(255, 255, 255, .08);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
border-radius: var(--radius-lg);
cursor: pointer;
transition: all var(--transition);
border: 2px solid transparent;
user-select: none;
overflow: hidden;
aspect-ratio: 1;
@ -953,15 +1004,14 @@
border-radius: inherit;
opacity: 0;
transition: opacity var(--transition);
background: radial-gradient(ellipse at center, var(--accent-glow) 0%, transparent 70%);
background: radial-gradient(circle at 50% 0%, rgba(var(--accent-rgb), .12), transparent 70%);
pointer-events: none;
}
.sound-card:hover {
background: var(--bg-tertiary);
transform: translateY(-3px);
box-shadow: var(--shadow-med), 0 0 20px var(--accent-glow);
border-color: rgba(88, 101, 242, .2);
transform: scale(1.05);
border-color: rgba(var(--accent-rgb), .35);
box-shadow: 0 4px 20px rgba(var(--accent-rgb), .15);
}
.sound-card:hover::before {
@ -969,7 +1019,7 @@
}
.sound-card:active {
transform: translateY(0);
transform: scale(0.97);
transition-duration: 50ms;
}
@ -992,7 +1042,7 @@
.ripple {
position: absolute;
border-radius: 50%;
background: rgba(88, 101, 242, .3);
background: rgba(var(--accent-rgb), .3);
transform: scale(0);
animation: ripple-expand 500ms ease-out forwards;
pointer-events: none;
@ -1171,8 +1221,8 @@
gap: 6px;
padding: 4px 12px;
border-radius: 20px;
background: rgba(var(--accent-rgb, 88, 101, 242), .12);
border: 1px solid rgba(var(--accent-rgb, 88, 101, 242), .2);
background: rgba(var(--accent-rgb), .12);
border: 1px solid rgba(var(--accent-rgb), .2);
font-size: 12px;
color: var(--text-muted);
max-width: none;
@ -1251,23 +1301,26 @@
.vol-slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 12px;
height: 12px;
width: 14px;
height: 14px;
border-radius: 50%;
background: var(--accent);
box-shadow: 0 0 8px rgba(var(--accent-rgb), .5);
cursor: pointer;
transition: transform var(--transition);
transition: transform var(--transition), box-shadow var(--transition);
}
.vol-slider::-webkit-slider-thumb:hover {
transform: scale(1.3);
box-shadow: 0 0 14px rgba(var(--accent-rgb), .7);
}
.vol-slider::-moz-range-thumb {
width: 12px;
height: 12px;
width: 14px;
height: 14px;
border-radius: 50%;
background: var(--accent);
box-shadow: 0 0 8px rgba(var(--accent-rgb), .5);
border: none;
cursor: pointer;
}
@ -2042,7 +2095,6 @@
z-index: 300;
animation: fade-in 150ms ease;
}
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
.dl-modal {
width: 420px; max-width: 92vw;

View file

@ -356,23 +356,26 @@
/* ── Empty state ── */
.stream-empty {
text-align: center;
padding: 60px 20px;
color: var(--text-muted);
flex: 1; display: flex; flex-direction: column;
align-items: center; justify-content: center; gap: 16px;
padding: 40px; height: 100%;
}
.stream-empty-icon {
font-size: 48px;
margin-bottom: 12px;
opacity: 0.4;
font-size: 64px; line-height: 1;
filter: drop-shadow(0 0 20px rgba(230,126,34,0.5));
animation: stream-float 3s ease-in-out infinite;
}
@keyframes stream-float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
.stream-empty h3 {
font-size: 18px;
font-weight: 600;
color: var(--text-normal);
margin-bottom: 6px;
font-size: 26px; font-weight: 700; color: #f2f3f5;
letter-spacing: -0.5px; margin: 0;
}
.stream-empty p {
font-size: 14px;
font-size: 15px; color: #80848e;
text-align: center; max-width: 360px; line-height: 1.5; margin: 0;
}
/* ── Error ── */

View file

@ -161,23 +161,26 @@
/* ── Empty state ── */
.wt-empty {
text-align: center;
padding: 60px 20px;
color: var(--text-muted);
flex: 1; display: flex; flex-direction: column;
align-items: center; justify-content: center; gap: 16px;
padding: 40px; height: 100%;
}
.wt-empty-icon {
font-size: 48px;
margin-bottom: 12px;
opacity: 0.4;
font-size: 64px; line-height: 1;
filter: drop-shadow(0 0 20px rgba(230,126,34,0.5));
animation: wt-float 3s ease-in-out infinite;
}
@keyframes wt-float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
.wt-empty h3 {
font-size: 18px;
font-weight: 600;
color: var(--text-normal);
margin-bottom: 6px;
font-size: 26px; font-weight: 700; color: #f2f3f5;
letter-spacing: -0.5px; margin: 0;
}
.wt-empty p {
font-size: 14px;
font-size: 15px; color: #80848e;
text-align: center; max-width: 360px; line-height: 1.5; margin: 0;
}
/* ── Error ── */