soundboardpanel.razor.scss
@import "/UI/Styles/_Theme.scss";
@import "/UI/Styles/_Fonts.scss";
@import "/UI/Components/Tile/Tile.scss";
@import "/UI/Components/Button/Button.scss";
SoundBoardPanel
{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: all;
overflow: hidden;
.sb
{
width: 100%;
height: 100%;
flex-direction: column;
background-color: $bg-0;
overflow: hidden;
}
.sb-shell
{
width: 100%;
height: 100%;
flex-direction: column;
flex-grow: 1;
flex-shrink: 1;
min-height: 0;
padding: 20px 24px 18px;
overflow: hidden;
}
.sb-topbar
{
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
height: 64px;
min-height: 64px;
max-height: 64px;
margin-bottom: 14px;
padding-bottom: 14px;
border-bottom: 1px solid $line;
flex-shrink: 0;
flex-wrap: nowrap;
overflow: hidden;
}
.sb-brand-block
{
display: flex;
align-items: center;
gap: 12px;
min-width: 0;
flex-grow: 1;
}
.sb-status-led
{
width: 10px;
height: 10px;
border-radius: 50%;
background-color: $bg-2;
border: 1px solid $line;
flex-shrink: 0;
&.is-live
{
background-color: $success;
border-color: $success-line;
}
}
.sb-brand-copy
{
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.sb-eyebrow
{
font-size: $fs-1;
font-weight: 700;
letter-spacing: $ls-xwide;
color: $text-faint;
font-family: $font-mono;
}
.sb-title
{
font-size: $fs-5;
font-weight: 800;
color: $text;
font-family: $font-primary;
white-space: nowrap;
overflow: hidden;
}
.sb-voice-chip
{
display: flex;
flex-direction: column;
justify-content: center;
gap: 6px;
width: 128px;
height: 52px;
min-width: 128px;
max-width: 128px;
padding: 8px 12px;
border-radius: 4px;
background-color: $bg-2;
border: 1px solid $line-strong;
flex-shrink: 0;
overflow: hidden;
}
.sb-voice-chip-head
{
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 8px;
}
.sb-voice-chip-label
{
font-size: $fs-1;
font-weight: 700;
letter-spacing: $ls-wide;
color: $text-faint;
font-family: $font-mono;
}
.sb-voice-chip-value
{
font-size: $fs-4;
font-weight: 800;
line-height: 1;
color: $accent;
font-family: $font-mono;
}
.sb-voice-meter-stack
{
width: 100%;
height: 18px;
min-height: 18px;
max-height: 18px;
flex-direction: column;
justify-content: flex-end;
gap: 2px;
overflow: hidden;
}
.sb-voice-meter-tier
{
width: 100%;
height: 3px;
min-height: 3px;
max-height: 3px;
border-radius: 999px;
background-color: $bg-inset;
overflow: hidden;
}
.sb-voice-meter-fill
{
height: 100%;
border-radius: 999px;
transition: width 0.16s ease;
}
.sb-tabs-bar
{
display: flex;
flex-direction: row;
flex-shrink: 0;
align-items: center;
gap: 8px;
width: 100%;
height: 48px;
margin-bottom: 10px;
pointer-events: all;
}
.sb-search-bar
{
display: flex;
flex-direction: row;
flex-shrink: 0;
align-items: center;
gap: 10px;
width: 100%;
height: 40px;
margin-bottom: 12px;
padding: 0 12px;
border-radius: 8px;
background-color: $bg-2;
border: 1px solid $line-strong;
pointer-events: all;
}
.sb-search-icon
{
flex-shrink: 0;
font-size: 16px;
font-weight: 700;
color: $text-faint;
line-height: 1;
}
.sb-search-input
{
flex-grow: 1;
flex-shrink: 1;
min-width: 0;
height: 36px;
min-height: 36px;
padding: 0 4px;
background-color: transparent;
border: 0;
color: $text;
font-size: $fs-2;
font-weight: 600;
font-family: $font-mono;
letter-spacing: 0.04em;
}
.sb-search-clear
{
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 6px;
background-color: $bg-inset;
border: 1px solid $line;
color: $text-dim;
font-size: 12px;
font-weight: 800;
cursor: pointer;
pointer-events: all;
&:hover
{
border-color: $accent;
color: $accent;
}
&:active
{
sound-in: "ui.button.press";
transform: scale(0.96);
}
}
.sb-search-count
{
flex-shrink: 0;
min-width: 36px;
text-align: right;
font-size: $fs-1;
font-weight: 700;
letter-spacing: $ls-wide;
color: $text-faint;
font-family: $font-mono;
white-space: nowrap;
}
.sb-empty
{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
min-height: 180px;
padding: 32px 16px;
pointer-events: none;
}
.sb-empty-title
{
font-size: $fs-4;
font-weight: 800;
color: $text-dim;
font-family: $font-mono;
letter-spacing: 0.08em;
}
.sb-empty-body
{
font-size: $fs-2;
font-weight: 500;
color: $text-faint;
font-family: $font-mono;
text-align: center;
}
.sb-tabs-arrow
{
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
width: 36px;
height: 40px;
border-radius: 8px;
background-color: $bg-2;
border: 1px solid $line-strong;
color: $text;
font-size: 22px;
font-weight: 800;
cursor: pointer;
pointer-events: all;
z-index: 2;
&:hover
{
border-color: $accent;
color: $accent;
}
&:active
{
sound-in: "ui.button.press";
transform: scale(0.96);
}
&.is-disabled
{
opacity: 0.35;
cursor: default;
pointer-events: none;
}
}
.sb-tabs-scroll
{
flex-grow: 1;
flex-shrink: 1;
min-width: 0;
height: 100%;
// Clip the track; scrolling is done via margin-left on .sb-tabs-track
// because Panel.ScrollSize often stays 0 for horizontal flex content.
overflow: hidden;
pointer-events: all;
}
.sb-tabs-track
{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
gap: 6px;
// Must grow with chips so content width > viewport (enables overflow).
width: auto;
flex-shrink: 0;
height: 100%;
padding: 2px 2px 4px;
// margin-left is driven from code for arrow / wheel scrolling.
}
.sb-tab-chip
{
display: flex;
flex-direction: row;
flex-shrink: 0;
align-items: center;
justify-content: center;
gap: 6px;
height: 36px;
padding: 0 14px;
border-radius: 6px;
background-color: $bg-2;
border: 1px solid $line-strong;
cursor: pointer;
pointer-events: all;
white-space: nowrap;
&:hover
{
border-color: $accent;
}
&.is-active
{
background-color: $accent;
border-color: $accent;
color: $accent-ink;
.sb-tab-chip-label
{
color: $accent-ink;
}
}
&.is-search
{
background-color: #2a6df4;
border-color: #5b8dff;
color: #fff;
.sb-tab-chip-label
{
color: #fff;
}
}
&:active
{
sound-in: "ui.button.press";
transform: scale(0.97);
}
}
.sb-tab-chip-icon
{
font-size: 13px;
flex-shrink: 0;
}
.sb-tab-chip-label
{
font-size: $fs-2;
font-weight: 700;
font-family: $font-mono;
letter-spacing: 1.2px;
color: $text-dim;
white-space: nowrap;
flex-shrink: 0;
}
.sb-board
{
flex-grow: 1;
flex-shrink: 1;
min-height: 0;
margin-bottom: 14px;
border: 1px solid $line;
background-color: $bg-1;
flex-direction: column;
overflow: hidden;
pointer-events: all;
}
.sb-board-scroll
{
flex-grow: 1;
flex-shrink: 1;
min-height: 0;
flex-direction: column;
overflow-y: scroll;
overflow-x: hidden;
pointer-events: all;
}
.sb-pad-content
{
flex-direction: column;
flex-shrink: 0;
width: 100%;
pointer-events: all;
}
.tile-grid
{
flex-direction: row;
flex-wrap: wrap;
align-content: flex-start;
width: 100%;
flex-shrink: 0;
gap: 12px;
padding: 8px;
pointer-events: all;
.tile
{
pointer-events: all;
flex-shrink: 0;
}
}
.sb-pad-grid
{
padding: 4px 4px 24px;
}
.tile
{
width: 112px;
&.is-loading
{
border-color: $line-strong;
.tile-swatch
{
opacity: 0.55;
}
.tile-label
{
color: $text-dim;
}
}
// Lobby co-op: pad lit by someone in the lobby (avatar + username).
&.is-remote
{
border-color: #5b8dff;
.tile-label
{
color: #e8f0ff;
background-color: rgba(42, 109, 244, 0.45);
font-weight: 800;
}
}
}
.tile-swatch
{
height: 64px;
position: relative;
}
.tile-remote-avatar
{
position: absolute;
top: 4px;
right: 4px;
width: 28px;
height: 28px;
border-radius: 50%;
background-size: cover;
background-position: center;
background-color: #0b1220;
border: 2px solid #ffffff;
z-index: 3;
pointer-events: none;
}
.tile-remote-name
{
position: absolute;
left: 3px;
right: 3px;
bottom: 3px;
padding: 2px 4px;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.72);
color: #ffffff;
font-size: 9px;
font-weight: 800;
font-family: $font-mono;
letter-spacing: 0.04em;
text-align: center;
text-transform: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
z-index: 3;
pointer-events: none;
}
.sb-controls
{
display: flex;
flex-direction: row;
align-items: center;
gap: 12px;
flex-shrink: 0;
min-height: 56px;
}
// LOOP + CO-OP share one baseline.
.sb-toggle-row
{
display: flex;
flex-direction: row;
align-items: center;
flex-shrink: 0;
gap: 10px;
}
.sb-toggle
{
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 100px;
height: 44px;
min-width: 100px;
min-height: 44px;
max-height: 44px;
padding: 0 12px;
border-radius: 10px;
font-size: 13px;
font-weight: 900;
letter-spacing: 0.16em;
color: #ffffff;
cursor: pointer;
pointer-events: all;
// s&box UI: use border shorthand only (border-style is invalid).
border: 3px solid #2a0000;
background-color: #c10f0f;
box-shadow: 0 3px 0 #3a0000, inset 0 1px 4px rgba(255, 255, 255, 0.2);
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.35);
&.is-on
{
border: 3px solid #0a3d14;
background-color: #1fbf3a;
box-shadow: 0 3px 0 #0f5a1c, 0 0 14px rgba(57, 255, 80, 0.35), inset 0 1px 4px rgba(255, 255, 255, 0.25);
}
&.is-off
{
border: 3px solid #2a0000;
background-color: #c10f0f;
box-shadow: 0 3px 0 #3a0000, inset 0 1px 4px rgba(255, 255, 255, 0.2);
}
// CO-OP on uses same green as LOOP (is-on); is-coop is optional marker.
&.is-on.is-coop
{
border: 3px solid #0a3d14;
background-color: #1fbf3a;
box-shadow: 0 3px 0 #0f5a1c, 0 0 14px rgba(57, 255, 80, 0.35), inset 0 1px 4px rgba(255, 255, 255, 0.25);
}
&:active
{
sound-in: "ui.button.press";
transform: translateY(2px);
}
}
.sb-now-playing
{
flex-grow: 1;
display: flex;
align-items: center;
gap: 10px;
min-width: 0;
padding: 10px 14px;
background-color: $bg-2;
border: 1px solid $line;
}
.sb-now-playing-dot
{
width: 8px;
height: 8px;
border-radius: 50%;
background-color: $line-strong;
flex-shrink: 0;
&.is-live
{
background-color: $accent;
}
}
.sb-now-playing-text
{
font-size: $fs-2;
font-weight: 600;
color: $text-dim;
font-family: $font-mono;
white-space: nowrap;
overflow: hidden;
}
.sb-kill-btn
{
min-width: 148px;
flex-shrink: 0;
}
&.is-wide
{
.tile
{
width: 120px;
}
}
&.is-medium
{
.sb-shell
{
padding: 18px 20px 16px;
}
.sb-title
{
font-size: $fs-4;
}
.tile
{
width: 104px;
}
}
&.is-compact
{
.sb-shell
{
padding: 14px 14px 12px;
}
.sb-voice-chip
{
width: 116px;
min-width: 116px;
max-width: 116px;
}
.tile
{
width: 96px;
}
.tile-swatch
{
height: 56px;
}
}
&.is-tight
{
.sb-shell
{
padding: 12px 10px 10px;
}
.sb-search-bar
{
height: 36px;
padding: 0 10px;
}
.sb-search-count
{
min-width: 28px;
font-size: 10px;
}
.sb-topbar
{
height: 58px;
min-height: 58px;
max-height: 58px;
}
.sb-voice-chip
{
width: 108px;
min-width: 108px;
max-width: 108px;
height: 48px;
min-height: 48px;
max-height: 48px;
}
.sb-voice-chip-value
{
font-size: $fs-3;
}
.sb-title
{
font-size: $fs-3;
}
.sb-tabs-bar
{
height: 44px;
}
.sb-tab-chip
{
height: 32px;
padding: 0 10px;
}
.sb-tab-chip-label
{
font-size: 11px;
}
.tile
{
width: 88px;
}
.tile-swatch
{
height: 50px;
}
.sb-controls
{
flex-wrap: wrap;
}
.sb-now-playing
{
width: 100%;
order: 3;
}
.sb-kill-btn
{
width: 100%;
order: 2;
}
}
&.has-voices
{
.sb-topbar
{
border-bottom-color: $accent-line;
}
}
.sb-ach
{
position: absolute;
left: 24px;
bottom: 28px;
display: flex;
flex-direction: row;
align-items: center;
gap: 14px;
max-width: 420px;
padding: 14px 18px;
border-radius: 12px;
background-color: rgba(12, 8, 20, 0.94);
border: 2px solid rgba(255, 210, 80, 0.75);
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.55), 0 0 24px rgba(255, 180, 40, 0.22);
pointer-events: none;
z-index: 50;
}
.sb-ach-icon
{
font-size: 28px;
flex-shrink: 0;
}
.sb-ach-copy
{
display: flex;
flex-direction: column;
gap: 3px;
min-width: 0;
}
.sb-ach-kicker
{
font-size: 9px;
font-weight: 800;
letter-spacing: 0.2em;
color: #ffd24a;
}
.sb-ach-title
{
font-size: 15px;
font-weight: 900;
letter-spacing: 0.04em;
color: #fff;
}
.sb-ach-body
{
font-size: 11px;
font-weight: 500;
letter-spacing: 0.02em;
color: rgba(255, 255, 255, 0.72);
white-space: normal;
}
}