added color/ theme settings, new config window
This commit is contained in:
@@ -58,11 +58,11 @@ export class PlayerControls extends LitElement {
|
||||
}
|
||||
|
||||
button:hover {
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.repeat-one {
|
||||
|
||||
@@ -22,23 +22,23 @@ export class SeekBar extends LitElement {
|
||||
--track-size: 6px;
|
||||
flex: 1;
|
||||
margin: 0 1em;
|
||||
--wa-tooltip-background-color: #343a40;
|
||||
--wa-tooltip-content-color: white;
|
||||
--wa-tooltip-border-color: #343a40;
|
||||
--wa-tooltip-background-color: var(--yj-bg-elevated, #343a40);
|
||||
--wa-tooltip-content-color: var(--yj-text-primary, white);
|
||||
--wa-tooltip-border-color: var(--yj-bg-elevated, #343a40);
|
||||
--wa-tooltip-border-radius: 4px;
|
||||
--wa-tooltip-font-size: 0.875em;
|
||||
}
|
||||
|
||||
wa-slider::part(track) {
|
||||
background: white;
|
||||
background: var(--yj-text-primary, white);
|
||||
}
|
||||
|
||||
wa-slider::part(indicator) {
|
||||
background: yellow;
|
||||
background: var(--yj-accent, yellow);
|
||||
}
|
||||
|
||||
wa-slider::part(thumb) {
|
||||
background: black;
|
||||
background: var(--yj-bg-base, black);
|
||||
}
|
||||
|
||||
#seek-bar-container {
|
||||
|
||||
@@ -35,8 +35,8 @@ export class VolumeControl extends LitElement {
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: #1a1a1a;
|
||||
border: 1px solid #333;
|
||||
background: var(--yj-bg-surface, #1a1a1a);
|
||||
border: 1px solid var(--yj-border-subtle, #333);
|
||||
border-radius: 8px;
|
||||
padding: 1em 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
@@ -52,16 +52,16 @@ export class VolumeControl extends LitElement {
|
||||
}
|
||||
|
||||
wa-slider::part(track) {
|
||||
background: white;
|
||||
background: var(--yj-text-primary, white);
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
wa-slider::part(indicator) {
|
||||
background: yellow;
|
||||
background: var(--yj-accent, yellow);
|
||||
}
|
||||
|
||||
wa-slider::part(thumb) {
|
||||
background: black;
|
||||
background: var(--yj-bg-base, black);
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
import { LitElement, html, css, nothing } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
|
||||
/**
|
||||
* Schema describing a single config field.
|
||||
*
|
||||
* The `type` controls which input widget is rendered:
|
||||
* - `text` – plain text input
|
||||
* - `select` – dropdown with `options`
|
||||
* - `color` – colour picker swatch
|
||||
* - `directory` – readonly text + browse button
|
||||
* - `number` – numeric input
|
||||
* - `toggle` – on/off switch
|
||||
*/
|
||||
export interface ConfigFieldSchema {
|
||||
key: string;
|
||||
label: string;
|
||||
description?: string;
|
||||
type:
|
||||
| 'text'
|
||||
| 'select'
|
||||
| 'color'
|
||||
| 'directory'
|
||||
| 'number'
|
||||
| 'toggle';
|
||||
options?: { value: string; label: string }[];
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export interface ConfigFieldChangeEvent {
|
||||
key: string;
|
||||
value: unknown;
|
||||
}
|
||||
|
||||
@customElement('config-field')
|
||||
export class ConfigField extends LitElement {
|
||||
static override styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: 1em;
|
||||
color-scheme: inherit;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.35em;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-size: 0.85em;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 0.75em;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.input-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
}
|
||||
|
||||
input[type='text'],
|
||||
input[type='number'] {
|
||||
background: var(--yj-bg-elevated, #343a40);
|
||||
color: var(--yj-text-primary, #fff);
|
||||
border: 1px solid var(--yj-border-subtle, #333);
|
||||
border-radius: 4px;
|
||||
padding: 0.4em 0.6em;
|
||||
font-size: 0.85em;
|
||||
font-family: inherit;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: 1px solid var(--yj-accent, #ffd43b);
|
||||
border-color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
input[readonly] {
|
||||
opacity: 0.8;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
select {
|
||||
background: var(--yj-bg-elevated, #343a40);
|
||||
color: var(--yj-text-primary, #fff);
|
||||
border: 1px solid var(--yj-border-subtle, #333);
|
||||
border-radius: 4px;
|
||||
padding: 0.4em 0.6em;
|
||||
font-size: 0.85em;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
outline: 1px solid var(--yj-accent, #ffd43b);
|
||||
border-color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
select option {
|
||||
background: var(--yj-bg-elevated, #343a40);
|
||||
color: var(--yj-text-primary, #fff);
|
||||
}
|
||||
|
||||
button {
|
||||
background: var(--yj-info, #4263eb);
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 0.4em 0.8em;
|
||||
font-size: 0.85em;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: var(--yj-info-hover, #3b5bdb);
|
||||
}
|
||||
|
||||
button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Colour picker */
|
||||
.color-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75em;
|
||||
}
|
||||
|
||||
input[type='color'] {
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
border: 2px solid var(--yj-border, #444);
|
||||
border-radius: 4px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
}
|
||||
|
||||
input[type='color']::-webkit-color-swatch-wrapper {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
input[type='color']::-webkit-color-swatch {
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.color-hex {
|
||||
font-family: monospace;
|
||||
font-size: 0.85em;
|
||||
color: var(--yj-text-secondary, #b3b3b3);
|
||||
}
|
||||
|
||||
/* Toggle */
|
||||
.toggle-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.toggle-switch {
|
||||
position: relative;
|
||||
width: 2.5em;
|
||||
height: 1.4em;
|
||||
}
|
||||
|
||||
.toggle-switch input {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.toggle-slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
inset: 0;
|
||||
background: var(--yj-bg-overlay, #495057);
|
||||
border-radius: 1em;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.toggle-slider::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 1em;
|
||||
width: 1em;
|
||||
left: 0.2em;
|
||||
bottom: 0.2em;
|
||||
background: white;
|
||||
border-radius: 50%;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.toggle-switch input:checked + .toggle-slider {
|
||||
background: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.toggle-switch input:checked + .toggle-slider::before {
|
||||
transform: translateX(1.1em);
|
||||
}
|
||||
`;
|
||||
|
||||
@property({ attribute: false })
|
||||
schema!: ConfigFieldSchema;
|
||||
|
||||
@property({ attribute: false })
|
||||
value: unknown = '';
|
||||
|
||||
override render() {
|
||||
if (!this.schema) return nothing;
|
||||
|
||||
return html`
|
||||
<div class="field">
|
||||
${this.schema.type === 'toggle'
|
||||
? this.renderToggle()
|
||||
: html`
|
||||
<label>${this.schema.label}</label>
|
||||
${this.renderInput()}
|
||||
`}
|
||||
${this.schema.description
|
||||
? html`<p class="description">
|
||||
${this.schema.description}
|
||||
</p>`
|
||||
: nothing}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderInput() {
|
||||
switch (this.schema.type) {
|
||||
case 'text':
|
||||
return this.renderText();
|
||||
case 'number':
|
||||
return this.renderNumber();
|
||||
case 'select':
|
||||
return this.renderSelect();
|
||||
case 'color':
|
||||
return this.renderColor();
|
||||
case 'directory':
|
||||
return this.renderDirectory();
|
||||
default:
|
||||
return html`<p>Unsupported field type</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
private renderText() {
|
||||
return html`
|
||||
<input
|
||||
type="text"
|
||||
.value=${String(this.value ?? '')}
|
||||
?disabled=${this.schema.disabled}
|
||||
@change=${this.onTextChange}
|
||||
/>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderNumber() {
|
||||
return html`
|
||||
<input
|
||||
type="number"
|
||||
.value=${String(this.value ?? '')}
|
||||
?disabled=${this.schema.disabled}
|
||||
@change=${this.onTextChange}
|
||||
/>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderSelect() {
|
||||
const current = String(this.value ?? '');
|
||||
|
||||
return html`
|
||||
<select
|
||||
?disabled=${this.schema.disabled}
|
||||
@change=${this.onSelectChange}
|
||||
>
|
||||
${(this.schema.options ?? []).map(
|
||||
(opt) => html`
|
||||
<option
|
||||
value=${opt.value}
|
||||
?selected=${opt.value === current}
|
||||
>
|
||||
${opt.label}
|
||||
</option>
|
||||
`,
|
||||
)}
|
||||
</select>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderColor() {
|
||||
const hex = String(this.value ?? '#ffffff');
|
||||
|
||||
return html`
|
||||
<div class="color-wrapper">
|
||||
<input
|
||||
type="color"
|
||||
.value=${hex}
|
||||
?disabled=${this.schema.disabled}
|
||||
@input=${this.onColorInput}
|
||||
/>
|
||||
<span class="color-hex">${hex}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderDirectory() {
|
||||
return html`
|
||||
<div class="input-row">
|
||||
<input
|
||||
type="text"
|
||||
.value=${String(this.value ?? '')}
|
||||
readonly
|
||||
/>
|
||||
<button
|
||||
?disabled=${this.schema.disabled}
|
||||
@click=${this.onBrowseClick}
|
||||
>
|
||||
Browse
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderToggle() {
|
||||
const checked = Boolean(this.value);
|
||||
|
||||
return html`
|
||||
<div class="toggle-row">
|
||||
<label>${this.schema.label}</label>
|
||||
<label class="toggle-switch">
|
||||
<input
|
||||
type="checkbox"
|
||||
?checked=${checked}
|
||||
?disabled=${this.schema.disabled}
|
||||
@change=${this.onToggleChange}
|
||||
/>
|
||||
<span class="toggle-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// EVENT DISPATCHERS
|
||||
// ===================================================================
|
||||
|
||||
private emitChange(value: unknown): void {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent<ConfigFieldChangeEvent>(
|
||||
'config-change',
|
||||
{
|
||||
detail: {
|
||||
key: this.schema.key,
|
||||
value,
|
||||
},
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
private onTextChange = (e: Event) => {
|
||||
const input = e.target as HTMLInputElement;
|
||||
this.emitChange(input.value);
|
||||
};
|
||||
|
||||
private onSelectChange = (e: Event) => {
|
||||
const select = e.target as HTMLSelectElement;
|
||||
this.emitChange(select.value);
|
||||
};
|
||||
|
||||
private onColorInput = (e: Event) => {
|
||||
const input = e.target as HTMLInputElement;
|
||||
this.value = input.value;
|
||||
this.emitChange(input.value);
|
||||
};
|
||||
|
||||
private onBrowseClick = () => {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('config-browse', {
|
||||
detail: { key: this.schema.key },
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
private onToggleChange = (e: Event) => {
|
||||
const input = e.target as HTMLInputElement;
|
||||
this.emitChange(input.checked);
|
||||
};
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'config-field': ConfigField;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
import { LitElement, html, css, nothing } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
|
||||
/**
|
||||
* A visual grouping wrapper for config fields.
|
||||
* Renders a heading, optional description, and a slot for fields.
|
||||
*/
|
||||
@customElement('config-section')
|
||||
export class ConfigSection extends LitElement {
|
||||
static override styles = css`
|
||||
:host {
|
||||
display: block;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
|
||||
.section {
|
||||
background: var(--yj-bg-surface, #212529);
|
||||
border: 1px solid var(--yj-border-subtle, #333);
|
||||
border-radius: 6px;
|
||||
padding: 1.25em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0 0 0.25em;
|
||||
font-size: 1em;
|
||||
font-weight: 700;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 0.8em;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
margin: 0 0 1em;
|
||||
}
|
||||
|
||||
.fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
@property({ type: String })
|
||||
heading = '';
|
||||
|
||||
@property({ type: String })
|
||||
description = '';
|
||||
|
||||
override render() {
|
||||
return html`
|
||||
<div class="section">
|
||||
<h3>${this.heading}</h3>
|
||||
${this.description
|
||||
? html`<p class="description">
|
||||
${this.description}
|
||||
</p>`
|
||||
: nothing}
|
||||
<div class="fields">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'config-section': ConfigSection;
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ export class AlbumDropdown extends LitElement {
|
||||
}
|
||||
|
||||
.album-dropdown {
|
||||
background-color: #343a40;
|
||||
background-color: var(--yj-bg-elevated, #343a40);
|
||||
border-radius: 0 0 4px 4px;
|
||||
padding: 12px 16px;
|
||||
box-sizing: border-box;
|
||||
@@ -81,7 +81,7 @@ export class AlbumDropdown extends LitElement {
|
||||
height: 0;
|
||||
border-left: 9px solid transparent;
|
||||
border-right: 9px solid transparent;
|
||||
border-bottom: 8px solid #343a40;
|
||||
border-bottom: 8px solid var(--yj-bg-elevated, #343a40);
|
||||
}
|
||||
|
||||
.dropdown-tracks {
|
||||
@@ -103,11 +103,9 @@ export class AlbumDropdown extends LitElement {
|
||||
}
|
||||
|
||||
.track-row:hover {
|
||||
background-color: rgba(
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
0.05
|
||||
background-color: var(
|
||||
--yj-hover-overlay,
|
||||
rgba(255, 255, 255, 0.05)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -121,13 +119,11 @@ export class AlbumDropdown extends LitElement {
|
||||
}
|
||||
|
||||
.track-row.active {
|
||||
background-color: rgba(
|
||||
255,
|
||||
212,
|
||||
59,
|
||||
0.1
|
||||
background-color: var(
|
||||
--yj-accent-bg,
|
||||
rgba(255, 212, 59, 0.1)
|
||||
);
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.track-row.selected.active {
|
||||
@@ -140,14 +136,14 @@ export class AlbumDropdown extends LitElement {
|
||||
}
|
||||
|
||||
.track-number {
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
min-width: 22px;
|
||||
text-align: right;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.track-title {
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
@@ -156,7 +152,7 @@ export class AlbumDropdown extends LitElement {
|
||||
}
|
||||
|
||||
.track-duration {
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@@ -203,21 +203,21 @@ export class CoverGrid extends LitElement {
|
||||
}
|
||||
|
||||
.album-card:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
background-color: var(--yj-hover-overlay, rgba(255, 255, 255, 0.1));
|
||||
}
|
||||
|
||||
.album-card.selected {
|
||||
outline: 2px solid #ffd43b;
|
||||
outline: 2px solid var(--yj-accent, #ffd43b);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.album-card.expanded {
|
||||
background-color: #343a40;
|
||||
background-color: var(--yj-bg-elevated, #343a40);
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
.album-card:focus-visible {
|
||||
outline: 2px solid #ffd43b;
|
||||
outline: 2px solid var(--yj-accent, #ffd43b);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ export class CoverGrid extends LitElement {
|
||||
aspect-ratio: 1;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
background-color: #282828;
|
||||
background-color: var(--yj-bg-surface, #282828);
|
||||
transition: scale 0.15s ease;
|
||||
}
|
||||
|
||||
@@ -263,8 +263,8 @@ export class CoverGrid extends LitElement {
|
||||
|
||||
.select-toggle.checked {
|
||||
opacity: 1;
|
||||
background-color: #ffd43b;
|
||||
border-color: #ffd43b;
|
||||
background-color: var(--yj-accent, #ffd43b);
|
||||
border-color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.check-icon {
|
||||
@@ -289,10 +289,10 @@ export class CoverGrid extends LitElement {
|
||||
justify-content: center;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
#404040 0%,
|
||||
#282828 100%
|
||||
var(--yj-bg-overlay, #404040) 0%,
|
||||
var(--yj-bg-surface, #282828) 100%
|
||||
);
|
||||
color: #b3b3b3;
|
||||
color: var(--yj-text-secondary, #b3b3b3);
|
||||
font-size: var(--placeholder-font, 48px);
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ export class CoverGrid extends LitElement {
|
||||
.album-name {
|
||||
font-size: var(--album-name-font, 14px);
|
||||
font-weight: 400;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -318,7 +318,7 @@ export class CoverGrid extends LitElement {
|
||||
|
||||
.artist-name {
|
||||
font-size: var(--artist-name-font, 12px);
|
||||
color: #b3b3b3;
|
||||
color: var(--yj-text-secondary, #b3b3b3);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -326,7 +326,7 @@ export class CoverGrid extends LitElement {
|
||||
}
|
||||
|
||||
.album-year {
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
}
|
||||
|
||||
/* ========================================
|
||||
@@ -338,7 +338,7 @@ export class CoverGrid extends LitElement {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 32px;
|
||||
color: #b3b3b3;
|
||||
color: var(--yj-text-secondary, #b3b3b3);
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
@@ -347,7 +347,7 @@ export class CoverGrid extends LitElement {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 48px;
|
||||
color: #b3b3b3;
|
||||
color: var(--yj-text-secondary, #b3b3b3);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -364,8 +364,8 @@ export class CoverGrid extends LitElement {
|
||||
}
|
||||
|
||||
.context-menu-panel {
|
||||
background-color: #343a40;
|
||||
border: 1px solid #444;
|
||||
background-color: var(--yj-bg-elevated, #343a40);
|
||||
border: 1px solid var(--yj-border, #444);
|
||||
border-radius: 6px;
|
||||
padding: 4px 0;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
||||
@@ -377,16 +377,14 @@ export class CoverGrid extends LitElement {
|
||||
}
|
||||
|
||||
.context-menu-panel wa-dropdown-item {
|
||||
--wa-color-text-normal: #fff;
|
||||
--wa-color-text-normal: var(--yj-text-primary, #fff);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.context-menu-panel wa-dropdown-item:hover {
|
||||
background-color: rgba(
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
0.1
|
||||
background-color: var(
|
||||
--yj-hover-overlay,
|
||||
rgba(255, 255, 255, 0.1)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ export class LibraryManager extends LitElement {
|
||||
:host {
|
||||
display: block;
|
||||
padding: 1.5em;
|
||||
color: #e9ecef;
|
||||
color: var(--yj-text-primary, #e9ecef);
|
||||
font-family: system-ui, -apple-system, sans-serif;
|
||||
overflow-y: auto;
|
||||
}
|
||||
@@ -251,13 +251,13 @@ export class LibraryManager extends LitElement {
|
||||
margin: 0 0 1em 0;
|
||||
font-size: 1.4em;
|
||||
font-weight: 600;
|
||||
color: #f8f9fa;
|
||||
color: var(--yj-text-primary, #f8f9fa);
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 2em;
|
||||
padding: 1.25em;
|
||||
background: #2b3035;
|
||||
background: var(--yj-bg-surface, #2b3035);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ export class LibraryManager extends LitElement {
|
||||
margin: 0 0 0.75em 0;
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
color: #dee2e6;
|
||||
color: var(--yj-text-primary, #dee2e6);
|
||||
}
|
||||
|
||||
.section-header {
|
||||
@@ -282,7 +282,7 @@ export class LibraryManager extends LitElement {
|
||||
.section-description {
|
||||
margin: 0 0 1em 0;
|
||||
font-size: 0.85em;
|
||||
color: #868e96;
|
||||
color: var(--yj-text-tertiary, #868e96);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
@@ -296,10 +296,10 @@ export class LibraryManager extends LitElement {
|
||||
.directory-path {
|
||||
flex: 1;
|
||||
padding: 0.5em 0.75em;
|
||||
background: #1a1d20;
|
||||
border: 1px solid #495057;
|
||||
background: var(--yj-bg-elevated, #1a1d20);
|
||||
border: 1px solid var(--yj-bg-overlay, #495057);
|
||||
border-radius: 4px;
|
||||
color: #adb5bd;
|
||||
color: var(--yj-text-secondary, #adb5bd);
|
||||
font-size: 0.85em;
|
||||
font-family: monospace;
|
||||
overflow: hidden;
|
||||
@@ -309,7 +309,7 @@ export class LibraryManager extends LitElement {
|
||||
}
|
||||
|
||||
.directory-path.has-value {
|
||||
color: #e9ecef;
|
||||
color: var(--yj-text-primary, #e9ecef);
|
||||
}
|
||||
|
||||
button {
|
||||
@@ -329,57 +329,57 @@ export class LibraryManager extends LitElement {
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: #4263eb;
|
||||
background: var(--yj-info, #4263eb);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover:not(:disabled) {
|
||||
background: #3b5bdb;
|
||||
background: var(--yj-info-hover, #3b5bdb);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background: #2f9e44;
|
||||
background: var(--yj-success, #2f9e44);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-success:hover:not(:disabled) {
|
||||
background: #2b8a3e;
|
||||
background: var(--yj-success-hover, #2b8a3e);
|
||||
}
|
||||
|
||||
.btn-warning {
|
||||
background: #e8590c;
|
||||
background: var(--yj-warning, #e8590c);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-warning:hover:not(:disabled) {
|
||||
background: #d9480f;
|
||||
background: var(--yj-warning-hover, #d9480f);
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
background: #e03131;
|
||||
background: var(--yj-error, #e03131);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-danger:hover:not(:disabled) {
|
||||
background: #c92a2a;
|
||||
background: var(--yj-error-hover, #c92a2a);
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
background: transparent;
|
||||
color: #868e96;
|
||||
color: var(--yj-text-tertiary, #868e96);
|
||||
padding: 0.3em 0.75em;
|
||||
font-size: 0.75em;
|
||||
border: 1px solid #495057;
|
||||
border: 1px solid var(--yj-bg-overlay, #495057);
|
||||
}
|
||||
|
||||
.btn-ghost:hover:not(:disabled) {
|
||||
background: #495057;
|
||||
color: #e9ecef;
|
||||
background: var(--yj-bg-overlay, #495057);
|
||||
color: var(--yj-text-primary, #e9ecef);
|
||||
}
|
||||
|
||||
.btn-ghost.copied {
|
||||
border-color: #2f9e44;
|
||||
color: #2f9e44;
|
||||
border-color: var(--yj-success, #2f9e44);
|
||||
color: var(--yj-success, #2f9e44);
|
||||
}
|
||||
|
||||
.setting-row {
|
||||
@@ -390,16 +390,16 @@ export class LibraryManager extends LitElement {
|
||||
}
|
||||
|
||||
.setting-row label {
|
||||
color: #adb5bd;
|
||||
color: var(--yj-text-secondary, #adb5bd);
|
||||
min-width: 8em;
|
||||
}
|
||||
|
||||
.setting-row select {
|
||||
padding: 0.4em 0.6em;
|
||||
background: #1a1d20;
|
||||
border: 1px solid #495057;
|
||||
background: var(--yj-bg-elevated, #1a1d20);
|
||||
border: 1px solid var(--yj-bg-overlay, #495057);
|
||||
border-radius: 4px;
|
||||
color: #e9ecef;
|
||||
color: var(--yj-text-primary, #e9ecef);
|
||||
font-size: 1em;
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
@@ -408,12 +408,12 @@ export class LibraryManager extends LitElement {
|
||||
|
||||
.setting-row select:focus {
|
||||
outline: none;
|
||||
border-color: #4263eb;
|
||||
border-color: var(--yj-info, #4263eb);
|
||||
}
|
||||
|
||||
.setting-row select option {
|
||||
background: #2b3035;
|
||||
color: #e9ecef;
|
||||
background: var(--yj-bg-surface, #2b3035);
|
||||
color: var(--yj-text-primary, #e9ecef);
|
||||
}
|
||||
|
||||
.scan-actions {
|
||||
@@ -425,15 +425,15 @@ export class LibraryManager extends LitElement {
|
||||
.status-bar {
|
||||
margin-top: 1.5em;
|
||||
padding: 0.75em 1em;
|
||||
background: #1a1d20;
|
||||
background: var(--yj-bg-elevated, #1a1d20);
|
||||
border-radius: 4px;
|
||||
font-size: 0.85em;
|
||||
color: #868e96;
|
||||
color: var(--yj-text-tertiary, #868e96);
|
||||
min-height: 1.2em;
|
||||
}
|
||||
|
||||
.status-bar.active {
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
/* --- Metrics tree --- */
|
||||
@@ -453,7 +453,7 @@ export class LibraryManager extends LitElement {
|
||||
cursor: pointer;
|
||||
padding: 0.25em 0;
|
||||
font-size: 0.85em;
|
||||
color: #ced4da;
|
||||
color: var(--yj-text-secondary, #ced4da);
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
@@ -484,21 +484,21 @@ export class LibraryManager extends LitElement {
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
color: #adb5bd;
|
||||
color: var(--yj-text-secondary, #adb5bd);
|
||||
}
|
||||
|
||||
.metric-value {
|
||||
color: #e9ecef;
|
||||
color: var(--yj-text-primary, #e9ecef);
|
||||
font-family: monospace;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.metric-value.highlight {
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.metric-note {
|
||||
color: #868e96;
|
||||
color: var(--yj-text-tertiary, #868e96);
|
||||
font-size: 0.75em;
|
||||
font-style: italic;
|
||||
padding-left: 1.35em;
|
||||
@@ -513,11 +513,11 @@ export class LibraryManager extends LitElement {
|
||||
}
|
||||
|
||||
.count-label {
|
||||
color: #adb5bd;
|
||||
color: var(--yj-text-secondary, #adb5bd);
|
||||
}
|
||||
|
||||
.count-value {
|
||||
color: #e9ecef;
|
||||
color: var(--yj-text-primary, #e9ecef);
|
||||
font-family: monospace;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -48,14 +48,14 @@ export class NowPlaying extends LitElement {
|
||||
.cover-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
background-color: var(--yj-bg-base, #000);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cover-placeholder wa-icon {
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ export class NowPlaying extends LitElement {
|
||||
|
||||
.track-artist {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
color: var(--yj-text-tertiary, #666);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -96,7 +96,7 @@ export class NowPlaying extends LitElement {
|
||||
|
||||
.resize-handle:hover,
|
||||
.resize-handle.dragging {
|
||||
background-color: #6c757d;
|
||||
background-color: var(--yj-text-tertiary, #6c757d);
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@ export class PlaylistPicker extends LitElement {
|
||||
}
|
||||
|
||||
.picker-panel {
|
||||
background-color: #343a40;
|
||||
border: 1px solid #444;
|
||||
background-color: var(--yj-bg-elevated, #343a40);
|
||||
border: 1px solid var(--yj-border, #444);
|
||||
border-radius: 6px;
|
||||
padding: 4px 0;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
||||
@@ -49,17 +49,17 @@ export class PlaylistPicker extends LitElement {
|
||||
|
||||
.picker-panel wa-dropdown-item {
|
||||
cursor: pointer;
|
||||
--wa-color-text-normal: #fff;
|
||||
--wa-color-text-normal: var(--yj-text-primary, #fff);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.picker-panel wa-dropdown-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
background-color: var(--yj-hover-overlay, rgba(255, 255, 255, 0.05));
|
||||
}
|
||||
|
||||
.separator {
|
||||
height: 1px;
|
||||
background: #555;
|
||||
background: var(--yj-border-subtle, #555);
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
@@ -71,10 +71,10 @@ export class PlaylistPicker extends LitElement {
|
||||
}
|
||||
|
||||
.create-form input {
|
||||
background: #2a2d30;
|
||||
border: 1px solid #555;
|
||||
background: var(--yj-bg-surface, #2b3035);
|
||||
border: 1px solid var(--yj-border-subtle, #555);
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
padding: 6px 8px;
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
@@ -82,11 +82,11 @@ export class PlaylistPicker extends LitElement {
|
||||
}
|
||||
|
||||
.create-form input:focus {
|
||||
border-color: #ffd43b;
|
||||
border-color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.create-form input::placeholder {
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
}
|
||||
|
||||
.button-row {
|
||||
@@ -96,10 +96,10 @@ export class PlaylistPicker extends LitElement {
|
||||
}
|
||||
|
||||
.button-row button {
|
||||
background: #495057;
|
||||
background: var(--yj-bg-overlay, #495057);
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
@@ -111,23 +111,23 @@ export class PlaylistPicker extends LitElement {
|
||||
}
|
||||
|
||||
.button-row button.primary {
|
||||
background: #ffd43b;
|
||||
background: var(--yj-accent, #ffd43b);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.button-row button.primary:hover {
|
||||
background: #ffe066;
|
||||
background: var(--yj-accent-hover, #ffe066);
|
||||
}
|
||||
|
||||
.button-row button.primary:disabled {
|
||||
background: #665a1e;
|
||||
color: #888;
|
||||
background: var(--yj-accent-muted, #665a1e);
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.empty-message {
|
||||
padding: 8px 12px;
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
font-size: 13px;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -205,21 +205,21 @@ export class PlaylistView
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid #333;
|
||||
border-bottom: 1px solid var(--yj-border-subtle, #333);
|
||||
}
|
||||
|
||||
.header h2 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
}
|
||||
|
||||
.new-playlist-button {
|
||||
background: none;
|
||||
border: 1px solid #555;
|
||||
border: 1px solid var(--yj-border-subtle, #555);
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
@@ -230,8 +230,8 @@ export class PlaylistView
|
||||
}
|
||||
|
||||
.new-playlist-button:hover {
|
||||
border-color: #ffd43b;
|
||||
color: #ffd43b;
|
||||
border-color: var(--yj-accent, #ffd43b);
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.create-form {
|
||||
@@ -239,16 +239,16 @@ export class PlaylistView
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid #333;
|
||||
border-bottom: 1px solid var(--yj-border-subtle, #333);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.create-form input {
|
||||
flex: 1;
|
||||
background: #2a2d30;
|
||||
border: 1px solid #555;
|
||||
background: var(--yj-bg-surface, #2b3035);
|
||||
border: 1px solid var(--yj-border-subtle, #555);
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
padding: 6px 10px;
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
@@ -256,18 +256,18 @@ export class PlaylistView
|
||||
}
|
||||
|
||||
.create-form input:focus {
|
||||
border-color: #ffd43b;
|
||||
border-color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.create-form input::placeholder {
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
}
|
||||
|
||||
.create-form button {
|
||||
background: #495057;
|
||||
background: var(--yj-bg-overlay, #495057);
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
@@ -275,21 +275,21 @@ export class PlaylistView
|
||||
}
|
||||
|
||||
.create-form button:hover {
|
||||
background: #5a6268;
|
||||
background: var(--yj-bg-overlay, #5a6268);
|
||||
}
|
||||
|
||||
.create-form button.primary {
|
||||
background: #ffd43b;
|
||||
background: var(--yj-accent, #ffd43b);
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.create-form button.primary:hover {
|
||||
background: #ffe066;
|
||||
background: var(--yj-accent-hover, #ffe066);
|
||||
}
|
||||
|
||||
.create-form button.primary:disabled {
|
||||
background: #665a1e;
|
||||
color: #888;
|
||||
background: var(--yj-accent-muted, #665a1e);
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ export class PlaylistView
|
||||
|
||||
.playlist-item {
|
||||
border-bottom: 1px solid
|
||||
rgba(255, 255, 255, 0.05);
|
||||
var(--yj-hover-overlay, rgba(255, 255, 255, 0.05));
|
||||
}
|
||||
|
||||
.playlist-header {
|
||||
@@ -316,18 +316,18 @@ export class PlaylistView
|
||||
}
|
||||
|
||||
.playlist-header:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
background-color: var(--yj-hover-overlay, rgba(255, 255, 255, 0.05));
|
||||
}
|
||||
|
||||
.playlist-item.drag-over > .playlist-header {
|
||||
background-color: rgba(255, 212, 59, 0.15);
|
||||
outline: 1px dashed #ffd43b;
|
||||
background-color: var(--yj-accent-bg-strong, rgba(255, 212, 59, 0.15));
|
||||
outline: 1px dashed var(--yj-accent, #ffd43b);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
|
||||
.chevron {
|
||||
font-size: 14px;
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
flex-shrink: 0;
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
@@ -338,13 +338,13 @@ export class PlaylistView
|
||||
|
||||
.playlist-icon {
|
||||
font-size: 18px;
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.playlist-name {
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -353,7 +353,7 @@ export class PlaylistView
|
||||
|
||||
.track-count {
|
||||
font-size: 11px;
|
||||
color: #666;
|
||||
color: var(--yj-text-tertiary, #666);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -370,9 +370,9 @@ export class PlaylistView
|
||||
|
||||
.play-all-button {
|
||||
background: none;
|
||||
border: 1px solid #555;
|
||||
border: 1px solid var(--yj-border-subtle, #555);
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
padding: 4px 10px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
@@ -383,8 +383,8 @@ export class PlaylistView
|
||||
}
|
||||
|
||||
.play-all-button:hover {
|
||||
border-color: #ffd43b;
|
||||
color: #ffd43b;
|
||||
border-color: var(--yj-accent, #ffd43b);
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.track-item {
|
||||
@@ -396,20 +396,20 @@ export class PlaylistView
|
||||
}
|
||||
|
||||
.track-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
background-color: var(--yj-hover-overlay, rgba(255, 255, 255, 0.05));
|
||||
}
|
||||
|
||||
.track-item.selected {
|
||||
background-color: rgba(100, 160, 255, 0.15);
|
||||
background-color: var(--yj-selection-bg, rgba(100, 160, 255, 0.15));
|
||||
}
|
||||
|
||||
.track-item.active {
|
||||
background-color: rgba(255, 212, 59, 0.1);
|
||||
color: #ffd43b;
|
||||
background-color: var(--yj-accent-bg, rgba(255, 212, 59, 0.1));
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.track-item.selected.active {
|
||||
background-color: rgba(100, 160, 255, 0.15);
|
||||
background-color: var(--yj-selection-bg, rgba(100, 160, 255, 0.15));
|
||||
}
|
||||
|
||||
.track-item.phantom {
|
||||
@@ -424,7 +424,7 @@ export class PlaylistView
|
||||
.phantom-badge {
|
||||
display: inline-block;
|
||||
font-size: 10px;
|
||||
color: #e67700;
|
||||
color: var(--yj-warning, #e67700);
|
||||
background: rgba(230, 119, 0, 0.15);
|
||||
padding: 1px 6px;
|
||||
border-radius: 3px;
|
||||
@@ -438,7 +438,7 @@ export class PlaylistView
|
||||
|
||||
.tracks-empty {
|
||||
padding: 12px 0;
|
||||
color: #666;
|
||||
color: var(--yj-text-tertiary, #666);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
@@ -447,7 +447,7 @@ export class PlaylistView
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 32px;
|
||||
color: #b3b3b3;
|
||||
color: var(--yj-text-secondary, #b3b3b3);
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
@@ -456,7 +456,7 @@ export class PlaylistView
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 48px 20px;
|
||||
color: #b3b3b3;
|
||||
color: var(--yj-text-secondary, #b3b3b3);
|
||||
text-align: center;
|
||||
gap: 8px;
|
||||
}
|
||||
@@ -474,8 +474,8 @@ export class PlaylistView
|
||||
}
|
||||
|
||||
.context-menu-panel {
|
||||
background-color: #343a40;
|
||||
border: 1px solid #444;
|
||||
background-color: var(--yj-bg-elevated, #343a40);
|
||||
border: 1px solid var(--yj-border, #444);
|
||||
border-radius: 6px;
|
||||
padding: 4px 0;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
||||
@@ -484,7 +484,7 @@ export class PlaylistView
|
||||
|
||||
.context-menu-panel wa-dropdown-item {
|
||||
cursor: pointer;
|
||||
--wa-color-text-normal: #fff;
|
||||
--wa-color-text-normal: var(--yj-text-primary, #fff);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
@@ -512,10 +512,10 @@ export class PlaylistView
|
||||
|
||||
.rename-input {
|
||||
flex: 1;
|
||||
background: #2a2d30;
|
||||
border: 1px solid #ffd43b;
|
||||
background: var(--yj-bg-surface, #2b3035);
|
||||
border: 1px solid var(--yj-accent, #ffd43b);
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
padding: 4px 8px;
|
||||
font-size: 14px;
|
||||
outline: none;
|
||||
@@ -525,9 +525,9 @@ export class PlaylistView
|
||||
|
||||
.import-button {
|
||||
background: none;
|
||||
border: 1px solid #555;
|
||||
border: 1px solid var(--yj-border-subtle, #555);
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
padding: 6px 12px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
@@ -538,8 +538,8 @@ export class PlaylistView
|
||||
}
|
||||
|
||||
.import-button:hover {
|
||||
border-color: #ffd43b;
|
||||
color: #ffd43b;
|
||||
border-color: var(--yj-accent, #ffd43b);
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ export class QueuePanel
|
||||
flex-shrink: 0;
|
||||
width: 0;
|
||||
overflow: hidden;
|
||||
background-color: #212529;
|
||||
background-color: var(--yj-bg-surface, #212529);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ export class QueuePanel
|
||||
--queue-width,
|
||||
${unsafeCSS(DEFAULT_WIDTH)}px
|
||||
);
|
||||
border-left: 1px solid #333;
|
||||
border-left: 1px solid var(--yj-border-subtle, #333);
|
||||
}
|
||||
|
||||
.resize-handle {
|
||||
@@ -180,7 +180,7 @@ export class QueuePanel
|
||||
|
||||
.resize-handle:hover,
|
||||
.resize-handle.dragging {
|
||||
background-color: #6c757d;
|
||||
background-color: var(--yj-text-tertiary, #6c757d);
|
||||
}
|
||||
|
||||
.panel-content {
|
||||
@@ -196,7 +196,7 @@ export class QueuePanel
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
border-bottom: 1px solid #333;
|
||||
border-bottom: 1px solid var(--yj-border-subtle, #333);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -223,11 +223,11 @@ export class QueuePanel
|
||||
}
|
||||
|
||||
.header-action-button:hover {
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.header-action-button:disabled {
|
||||
color: #555;
|
||||
color: var(--yj-border-subtle, #555);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ export class QueuePanel
|
||||
padding: 8px 16px;
|
||||
gap: 12px;
|
||||
border-bottom: 1px solid
|
||||
rgba(255, 255, 255, 0.05);
|
||||
var(--yj-hover-overlay, rgba(255, 255, 255, 0.05));
|
||||
cursor: default;
|
||||
user-select: none;
|
||||
width: 100%;
|
||||
@@ -255,30 +255,30 @@ export class QueuePanel
|
||||
}
|
||||
|
||||
.track-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
background-color: var(--yj-hover-overlay, rgba(255, 255, 255, 0.05));
|
||||
}
|
||||
|
||||
.track-item.selected {
|
||||
background-color: rgba(100, 160, 255, 0.15);
|
||||
background-color: var(--yj-selection-bg, rgba(100, 160, 255, 0.15));
|
||||
}
|
||||
|
||||
.track-item.active {
|
||||
background-color: rgba(255, 212, 59, 0.1);
|
||||
background-color: var(--yj-accent-bg, rgba(255, 212, 59, 0.1));
|
||||
}
|
||||
|
||||
.track-item.selected.active {
|
||||
background-color: rgba(100, 160, 255, 0.15);
|
||||
background-color: var(--yj-selection-bg, rgba(100, 160, 255, 0.15));
|
||||
}
|
||||
|
||||
.track-position {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
min-width: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.track-item.active .track-position {
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.track-details {
|
||||
@@ -297,12 +297,12 @@ export class QueuePanel
|
||||
}
|
||||
|
||||
.track-item.active .track-title {
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.track-artist {
|
||||
font-size: 11px;
|
||||
color: #b3b3b3;
|
||||
color: var(--yj-text-secondary, #b3b3b3);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -311,7 +311,7 @@ export class QueuePanel
|
||||
.remove-button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
display: flex;
|
||||
@@ -325,11 +325,11 @@ export class QueuePanel
|
||||
}
|
||||
|
||||
.remove-button:hover {
|
||||
color: #ff6b6b;
|
||||
color: var(--yj-error, #ff6b6b);
|
||||
}
|
||||
|
||||
.panel-content.drag-over {
|
||||
outline: 2px dashed #ffd43b;
|
||||
outline: 2px dashed var(--yj-accent, #ffd43b);
|
||||
outline-offset: -2px;
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ export class QueuePanel
|
||||
padding: 12px 16px;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
border-bottom: 1px solid
|
||||
rgba(255, 212, 59, 0.2);
|
||||
}
|
||||
@@ -355,7 +355,7 @@ export class QueuePanel
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
height: 2px;
|
||||
background: #ffd43b;
|
||||
background: var(--yj-accent, #ffd43b);
|
||||
border-radius: 1px;
|
||||
z-index: 5;
|
||||
pointer-events: none;
|
||||
@@ -368,7 +368,7 @@ export class QueuePanel
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
height: 2px;
|
||||
background: #ffd43b;
|
||||
background: var(--yj-accent, #ffd43b);
|
||||
border-radius: 1px;
|
||||
z-index: 5;
|
||||
pointer-events: none;
|
||||
@@ -380,7 +380,7 @@ export class QueuePanel
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40px 20px;
|
||||
color: #b3b3b3;
|
||||
color: var(--yj-text-secondary, #b3b3b3);
|
||||
text-align: center;
|
||||
gap: 8px;
|
||||
}
|
||||
@@ -394,8 +394,8 @@ export class QueuePanel
|
||||
}
|
||||
|
||||
.context-menu-panel {
|
||||
background-color: #343a40;
|
||||
border: 1px solid #444;
|
||||
background-color: var(--yj-bg-elevated, #343a40);
|
||||
border: 1px solid var(--yj-border, #444);
|
||||
border-radius: 6px;
|
||||
padding: 4px 0;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
||||
@@ -404,7 +404,7 @@ export class QueuePanel
|
||||
|
||||
.context-menu-panel wa-dropdown-item {
|
||||
cursor: pointer;
|
||||
--wa-color-text-normal: #fff;
|
||||
--wa-color-text-normal: var(--yj-text-primary, #fff);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { LitElement, html, css } from 'lit';
|
||||
import { customElement, state } from 'lit/decorators.js';
|
||||
import '@awesome.me/webawesome/dist/components/icon/icon.js';
|
||||
|
||||
import type { DragActiveDetail } from '@utils/drag-controller';
|
||||
|
||||
type View = 'home' | 'libraries' | 'playlists' | 'artists' | 'albums' | 'tracks';
|
||||
type View = 'home' | 'libraries' | 'playlists' | 'artists' | 'albums' | 'tracks' | 'settings';
|
||||
|
||||
interface NavItem {
|
||||
id: View;
|
||||
label: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
const MIN_WIDTH = 120;
|
||||
@@ -21,7 +23,7 @@ export class AppSidebar extends LitElement {
|
||||
display: block;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
background-color: #212529;
|
||||
background-color: var(--yj-bg-surface, #212529);
|
||||
min-width: ${MIN_WIDTH}px;
|
||||
max-width: ${MAX_WIDTH}px;
|
||||
}
|
||||
@@ -40,7 +42,7 @@ export class AppSidebar extends LitElement {
|
||||
|
||||
.resize-handle:hover,
|
||||
.resize-handle.dragging {
|
||||
background-color: #6c757d;
|
||||
background-color: var(--yj-text-tertiary, #6c757d);
|
||||
}
|
||||
|
||||
ul {
|
||||
@@ -50,19 +52,28 @@ export class AppSidebar extends LitElement {
|
||||
}
|
||||
|
||||
li {
|
||||
text-align: left;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.6em;
|
||||
border-radius: 5px;
|
||||
padding: 0.5em;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.15s ease;
|
||||
}
|
||||
|
||||
li wa-icon {
|
||||
font-size: 0.9em;
|
||||
flex-shrink: 0;
|
||||
width: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
li:hover {
|
||||
background-color: #343a40;
|
||||
background-color: var(--yj-bg-elevated, #343a40);
|
||||
}
|
||||
|
||||
li.active {
|
||||
background-color: #495057;
|
||||
background-color: var(--yj-bg-overlay, #495057);
|
||||
}
|
||||
|
||||
li p {
|
||||
@@ -73,8 +84,8 @@ export class AppSidebar extends LitElement {
|
||||
}
|
||||
|
||||
li.drag-hover {
|
||||
background-color: rgba(255, 212, 59, 0.15);
|
||||
outline: 1px dashed #ffd43b;
|
||||
background-color: var(--yj-accent-bg-strong, rgba(255, 212, 59, 0.15));
|
||||
outline: 1px dashed var(--yj-accent, #ffd43b);
|
||||
outline-offset: -1px;
|
||||
}
|
||||
`;
|
||||
@@ -101,12 +112,13 @@ export class AppSidebar extends LitElement {
|
||||
> | null = null;
|
||||
|
||||
private navItems: NavItem[] = [
|
||||
{ id: 'home', label: 'Home' },
|
||||
{ id: 'libraries', label: 'Libraries' },
|
||||
{ id: 'playlists', label: 'Playlists' },
|
||||
{ id: 'artists', label: 'Artists' },
|
||||
{ id: 'albums', label: 'Albums' },
|
||||
{ id: 'tracks', label: 'Tracks' },
|
||||
{ id: 'home', label: 'Home', icon: 'house' },
|
||||
{ id: 'libraries', label: 'Libraries', icon: 'folder-open' },
|
||||
{ id: 'playlists', label: 'Playlists', icon: 'list' },
|
||||
{ id: 'artists', label: 'Artists', icon: 'user-group' },
|
||||
{ id: 'albums', label: 'Albums', icon: 'compact-disc' },
|
||||
{ id: 'tracks', label: 'Tracks', icon: 'music' },
|
||||
{ id: 'settings', label: 'Settings', icon: 'gear' },
|
||||
];
|
||||
|
||||
override connectedCallback() {
|
||||
@@ -179,6 +191,9 @@ export class AppSidebar extends LitElement {
|
||||
@drop=${(e: DragEvent) =>
|
||||
this.onNavDrop(e)}
|
||||
>
|
||||
<wa-icon
|
||||
name=${item.icon}
|
||||
></wa-icon>
|
||||
<p>${item.label}</p>
|
||||
</li>
|
||||
`;
|
||||
|
||||
@@ -63,14 +63,14 @@ export class TrackInfo extends LitElement {
|
||||
.cover-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #2a2d30;
|
||||
background-color: var(--yj-bg-elevated, #2a2d30);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cover-placeholder wa-icon {
|
||||
color: #666;
|
||||
color: var(--yj-text-tertiary, #666);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ export class TrackInfo extends LitElement {
|
||||
.title {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -93,7 +93,7 @@ export class TrackInfo extends LitElement {
|
||||
|
||||
.secondary {
|
||||
font-size: 11px;
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -101,7 +101,7 @@ export class TrackInfo extends LitElement {
|
||||
|
||||
.duration {
|
||||
font-size: 12px;
|
||||
color: #888;
|
||||
color: var(--yj-text-tertiary, #888);
|
||||
flex-shrink: 0;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
@@ -252,8 +252,8 @@ export class TrackList extends LitElement implements SelectionHost {
|
||||
grid-template-columns: var(--grid-cols, 1fr 1fr 80px);
|
||||
padding: 8px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
border-bottom: 1px solid #666;
|
||||
color: var(--yj-text-primary, #fff);
|
||||
border-bottom: 1px solid var(--yj-text-tertiary, #666);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ export class TrackList extends LitElement implements SelectionHost {
|
||||
width: 1px;
|
||||
cursor: col-resize;
|
||||
pointer-events: auto;
|
||||
background-color: #444;
|
||||
background-color: var(--yj-border, #444);
|
||||
transition: background-color 0.15s ease;
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ export class TrackList extends LitElement implements SelectionHost {
|
||||
|
||||
.col-resize-handle:hover,
|
||||
.col-resize-handle.active {
|
||||
background-color: #6c757d;
|
||||
background-color: var(--yj-text-tertiary, #6c757d);
|
||||
}
|
||||
|
||||
lit-virtualizer {
|
||||
@@ -307,7 +307,7 @@ export class TrackList extends LitElement implements SelectionHost {
|
||||
grid-template-columns: var(--grid-cols, 1fr 1fr 80px);
|
||||
font-size: 12px;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #333;
|
||||
border-bottom: 1px solid var(--yj-border-subtle, #333);
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
cursor: default;
|
||||
@@ -324,23 +324,23 @@ export class TrackList extends LitElement implements SelectionHost {
|
||||
}
|
||||
|
||||
.track-row:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
background-color: var(--yj-hover-overlay, rgba(255, 255, 255, 0.05));
|
||||
}
|
||||
|
||||
.track-row.selected {
|
||||
background-color: rgba(100, 160, 255, 0.15);
|
||||
background-color: var(--yj-selection-bg, rgba(100, 160, 255, 0.15));
|
||||
}
|
||||
|
||||
.track-row.active {
|
||||
background-color: rgba(255, 212, 59, 0.1);
|
||||
background-color: var(--yj-accent-bg, rgba(255, 212, 59, 0.1));
|
||||
}
|
||||
|
||||
.track-row.active {
|
||||
color: #ffd43b;
|
||||
color: var(--yj-accent, #ffd43b);
|
||||
}
|
||||
|
||||
.track-row.selected.active {
|
||||
background-color: rgba(100, 160, 255, 0.15);
|
||||
background-color: var(--yj-selection-bg, rgba(100, 160, 255, 0.15));
|
||||
}
|
||||
|
||||
.track-name {
|
||||
@@ -363,8 +363,8 @@ export class TrackList extends LitElement implements SelectionHost {
|
||||
}
|
||||
|
||||
.context-menu-panel {
|
||||
background-color: #343a40;
|
||||
border: 1px solid #444;
|
||||
background-color: var(--yj-bg-elevated, #343a40);
|
||||
border: 1px solid var(--yj-border, #444);
|
||||
border-radius: 6px;
|
||||
padding: 4px 0;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
||||
@@ -376,12 +376,12 @@ export class TrackList extends LitElement implements SelectionHost {
|
||||
}
|
||||
|
||||
.context-menu-panel wa-dropdown-item {
|
||||
--wa-color-text-normal: #fff;
|
||||
--wa-color-text-normal: var(--yj-text-primary, #fff);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.context-menu-panel wa-dropdown-item:hover {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
background-color: var(--yj-hover-overlay, rgba(255, 255, 255, 0.1));
|
||||
}
|
||||
|
||||
.submenu-item {
|
||||
|
||||
Reference in New Issue
Block a user