Files
yellowjacket/frontend/src/components/cover-grid/cover-grid-styles.ts
T
yonlu 2825373c3c fix: add height:100% to all views missing it — eliminates top gap
Views with contain:layout in shadow DOM need explicit height:100%
on :host so their internal flex layout fills the parent's flex
space. Without it, the component doesn't know its height and the
internal content doesn't stretch to fill the panel.

Added height:100% to: cover-grid, artists-view, genres-view,
playlist-view, track-list, config-page (also box-sizing).
explore-view and detail views already had it.
2026-03-30 04:03:51 -04:00

289 lines
6.8 KiB
TypeScript

import { css } from 'lit';
import { contextMenuStyles } from '@utils/context-menu-controller.js';
import { designTokens } from '../../styles/tokens.css';
/** Component-specific styles for the cover grid. */
const gridStyles = css`
:host {
display: flex;
flex-direction: column;
overflow: hidden;
height: 100%;
position: relative;
contain: layout style;
}
/* ========================================
* Sort toolbar
* ======================================== */
.sort-toolbar {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
font-size: var(--yj-text-sm);
color: var(
--yj-text-secondary,
#b3b3b3
);
border-bottom: 1px solid
var(--yj-border-subtle, #333);
flex-shrink: 0;
user-select: none;
}
.sort-anchor {
display: inline-flex;
align-items: center;
gap: 4px;
cursor: pointer;
padding: 2px 6px;
border-radius: 4px;
background: transparent;
border: none;
color: inherit;
font: inherit;
}
.sort-anchor:hover {
background: var(
--yj-hover-overlay,
rgba(255, 255, 255, 0.05)
);
}
.sort-anchor .sort-label {
color: var(--yj-text-primary, #fff);
}
.sort-dir-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
cursor: pointer;
border: none;
border-radius: 4px;
background: transparent;
color: var(
--yj-text-secondary,
#b3b3b3
);
font-size: var(--yj-text-sm);
padding: 0;
}
.sort-dir-btn:hover {
background: var(
--yj-hover-overlay,
rgba(255, 255, 255, 0.05)
);
color: var(--yj-text-primary, #fff);
}
.sort-dropdown-panel {
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);
min-width: 140px;
}
.sort-dropdown-panel wa-dropdown-item {
cursor: pointer;
--wa-color-text-normal: var(
--yj-text-primary,
#fff
);
font-size: var(--yj-text-md);
}
.sort-dropdown-panel
wa-dropdown-item:hover {
background-color: var(
--yj-hover-overlay,
rgba(255, 255, 255, 0.1)
);
}
.sort-dropdown-panel
wa-dropdown-item.active-sort {
color: var(--yj-accent, #ffd43b);
--wa-color-text-normal: var(
--yj-accent,
#ffd43b
);
}
#sort-dropdown {
z-index: 200;
}
.grid-scroll-container {
flex: 1;
position: relative;
overflow-y: auto;
contain: paint;
}
/* ========================================
* Album card
* ======================================== */
.album-card {
display: flex;
flex-direction: column;
cursor: pointer;
padding: 5px;
/* border-radius removed — forces anti-aliased path clipping on
every paint of every visible card; cover image retains its own
4px radius via .cover-container */
box-sizing: border-box;
width: var(--card-width, 176px);
}
.album-card:hover {
background-color: var(--yj-hover-overlay, rgba(255, 255, 255, 0.1));
}
.album-card.selected {
outline: 2px solid var(--yj-accent, #ffd43b);
outline-offset: 2px;
}
.album-card:focus-visible {
outline: 2px solid var(--yj-accent, #ffd43b);
outline-offset: 2px;
}
.cover-container {
position: relative;
width: 100%;
aspect-ratio: 1;
border-radius: 4px;
overflow: hidden;
background-color: var(--yj-bg-surface, #282828);
/* transition removed — software rendering repaints per frame */
}
.album-card.selected .cover-container {
scale: 0.95;
}
.cover-image {
width: 100%;
height: 100%;
object-fit: cover;
-webkit-user-drag: none;
}
.placeholder-cover {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(
135deg,
var(--yj-bg-overlay, #404040) 0%,
var(--yj-bg-surface, #282828) 100%
);
color: var(--yj-text-secondary, #b3b3b3);
font-size: var(--placeholder-font, 48px);
}
.album-info {
margin-top: 4px;
min-width: 0;
text-align: center;
/* transition removed — software rendering repaints per frame */
}
.album-card.selected .album-info {
scale: 0.95;
}
.album-name {
font-size: var(--album-name-font, 14px);
font-weight: 400;
color: var(--yj-text-primary, #fff);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.artist-name {
font-size: var(--artist-name-font, 12px);
color: var(--yj-text-secondary, #b3b3b3);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-top: 2px;
}
.album-year {
color: var(--yj-text-tertiary, #888);
}
/* ========================================
* Shared states
* ======================================== */
.loading {
display: flex;
justify-content: center;
align-items: center;
padding: 32px;
color: var(--yj-text-secondary, #b3b3b3);
}
.sort-toolbar {
position: relative;
}
.search-indicator {
position: absolute;
left: 50%;
transform: translateX(-50%);
pointer-events: none;
background: var(--yj-bg-overlay, #495057);
color: var(--yj-text-secondary, #b3b3b3);
font-size: var(--yj-text-sm);
padding: 2px 14px;
border-radius: 12px;
border: 1px solid
var(--yj-border-subtle, #555);
white-space: nowrap;
opacity: 0.92;
}
.empty-state {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 48px;
color: var(--yj-text-secondary, #b3b3b3);
text-align: center;
}
.empty-state p {
margin: 8px 0;
}
`;
/** Combined styles for the cover grid component. */
export const coverGridStyles = [
designTokens,
gridStyles,
contextMenuStyles,
];