/* Core Design System & Redesign Utility Styles */

:root {
    --primary: #00e1ab;
    --primary-hover: #36ffc4;
    --secondary: #cfbdff;
    --bg-base: #0A0A0B;
    --bg-surface: #131314;
    --bg-surface-highest: #353436;
    --text-base: #e5e2e3;
    --text-muted: #b9cbc1;
    --outline: #27272A;
}

/* Glassmorphism templates */
.glass-panel {
    background: rgba(22, 22, 24, 0.7);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid rgba(255, 255, 255, 0.05);
}

.glass-card {
    background: rgba(22, 22, 24, 0.5);
    backdrop-filter: blur(15px);
    -webkit-backdrop-filter: blur(15px);
    border: 1px solid rgba(255, 255, 255, 0.03);
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.glass-card:hover {
    background: rgba(30, 30, 32, 0.65);
    border-color: rgba(0, 225, 171, 0.2);
    transform: translateY(-4px);
    box-shadow: 0 10px 40px -10px rgba(0, 225, 171, 0.25);
}

/* Glow effects */
.neon-glow {
    box-shadow: 0 0 30px rgba(0, 225, 171, 0.15);
}

.active-glow {
    box-shadow: 0 0 40px rgba(0, 225, 171, 0.2);
}

/* Text clipping */
.gradient-text {
    background: linear-gradient(135deg, #fbfffa 0%, #00e1ab 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* Progress track gradient */
.track-progress {
    background: linear-gradient(90deg, #cfbdff 0%, #00e1ab 100%);
}

.track-gradient {
    background: linear-gradient(90deg, #cfbdff 0%, #00e1ab 100%);
}

/* Custom scrollbars */
.custom-scrollbar::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

.custom-scrollbar::-webkit-scrollbar-track {
    background: transparent;
}

.custom-scrollbar::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.08);
    border-radius: 999px;
}

.custom-scrollbar::-webkit-scrollbar-thumb:hover {
    background: rgba(0, 225, 171, 0.3);
}

/* Lyrics fade masking parent container */
.lyric-fade-mask {
    mask-image: linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 12%, black 88%, transparent 100%);
}

/* Progressive Lyrics Styling */
.lyrics-wrapper {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 28px;
    padding-top: 40vh;
    padding-bottom: 40vh;
}

.lyric-line {
    font-family: 'Hanken Grotesk', sans-serif;
    font-weight: 700;
    font-size: 2.2rem;
    line-height: 1.4;
    color: rgba(255, 255, 255, 0.28);
    /* Dimmed future/default lines */
    letter-spacing: -0.03em;
    cursor: pointer;
    transform-origin: left center;
    transition: color 0.4s cubic-bezier(0.25, 0.8, 0.25, 1),
        transform 0.4s cubic-bezier(0.25, 0.8, 0.25, 1),
        opacity 0.4s cubic-bezier(0.25, 0.8, 0.25, 1),
        filter 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
    user-select: none;
    text-align: left;
    overflow-wrap: break-word;
    filter: blur(0.5px);
    /* Soft focus default */
}

.lyric-line:hover {
    color: rgba(255, 255, 255, 0.75);
    filter: blur(0px);
}

.lyric-line.past {
    color: rgba(255, 255, 255, 0.18);
    /* Aggressively dimmed past lines */
    filter: blur(1.2px);
    /* Blurred past lines for depth of field */
}

.lyric-line.active {
    color: #ffffff;
    font-weight: 800;
    transform: scale(1.08);
    /* Smooth scale transform (preventing layout reflow) */
    opacity: 1;
    filter: blur(0px);
    /* Sharp active focus */
}

.lyric-line.future {
    color: rgba(255, 255, 255, 0.28);
    filter: blur(0.5px);
}

.lyric-line.rtl {
    /* Spotify-style RTL: lines lean to the right edge and read right-to-left.
       transform-origin: right keeps the active line's scale anchored at the right
       boundary so it grows leftward into empty space instead of clipping past it
       (the pr-6 on the scroll container leaves room for the glow). */
    direction: rtl;
    text-align: right;
    transform-origin: right center;
}

/* Raw (un-synced) lyrics shown instantly while CTC alignment runs. No line is
   "active" yet, so lift them above the dim default and disable the pointer hint. */
.lyric-line.unsynced {
    color: rgba(255, 255, 255, 0.62);
    cursor: default;
    filter: blur(0px);
}

/* Word progressive tags */
.lyric-word {
    display: inline-block;
    color: rgba(255, 255, 255, 0.40);
    transition: color 0.3s cubic-bezier(0.25, 0.8, 0.25, 1),
        transform 0.25s cubic-bezier(0.25, 0.8, 0.25, 1),
        text-shadow 0.25s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.lyric-line:hover .lyric-word {
    color: rgba(255, 255, 255, 0.65);
}

.lyric-line.past .lyric-word {
    color: inherit;
    /* Dim past words to match line style */
}

.lyric-line.active .lyric-word {
    color: rgba(255, 255, 255, 0.35);
}

.lyric-line.active .lyric-word.sung {
    color: #ffffff;
}

.lyric-line.active .lyric-word.active-word {
    color: #ffffff;
    transform: scale(1.08);
    text-shadow: 0 0 15px rgba(255, 255, 255, 0.8);
}

/* Karaoke Mode Highlights */
body.karaoke-active .lyric-line.active .lyric-word.sung {
    color: #00e1ab;
    text-shadow: 0 0 12px rgba(0, 225, 171, 0.6);
}

body.karaoke-active .lyric-line.active .lyric-word.active-word {
    color: #36ffc4;
    transform: scale(1.1);
    text-shadow: 0 0 20px rgba(0, 225, 171, 0.9);
}

body.karaoke-active .lyric-line.past .lyric-word {
    color: #00e1ab;
    opacity: 0.25;
    /* Translucent green tint for past lines in Karaoke */
}

/* Karaoke queued while the song is still syncing — pulse to show it's pending */
#btn-karaoke-toggle.karaoke-pending {
    color: #00e1ab;
    animation: karaokePendingPulse 1.2s ease-in-out infinite;
}

@keyframes karaokePendingPulse {
    0%, 100% { opacity: 0.45; }
    50%      { opacity: 1; }
}

.lyric-status-msg {
    font-size: 20px;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.4);
    text-align: center;
    padding: 40px 20px;
    width: 100%;
}

/* Toast System */
.toast-container {
    position: fixed;
    top: 24px;
    right: 24px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    z-index: 9999;
}

.toast {
    background: rgba(32, 31, 32, 0.9);
    backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.1);
    color: #ffffff;
    padding: 14px 24px;
    border-radius: 12px;
    font-size: 14px;
    font-weight: 600;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    gap: 12px;
    animation: slideIn 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
    min-width: 300px;
    max-width: 450px;
    cursor: pointer;
    transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1), 
                background-color 0.2s ease, 
                opacity 0.2s ease;
}

.toast:hover {
    transform: scale(1.02);
    background: rgba(42, 41, 42, 0.95);
}

.toast.toast-success {
    border-left: 4px solid #00e1ab;
}

.toast.toast-error {
    border-left: 4px solid #ffb4ab;
}

.toast.toast-warning {
    border-left: 4px solid #ffe149;
}

.toast.toast-info {
    border-left: 4px solid #cfbdff;
}

@keyframes slideIn {
    from {
        transform: translateX(100%);
        opacity: 0;
    }

    to {
        transform: translateX(0);
        opacity: 1;
    }
}

/* Spinners */
.spinner {
    width: 40px;
    height: 40px;
    border: 3px solid rgba(255, 255, 255, 0.05);
    border-top: 3px solid #00e1ab;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

/* Vocal Separation Overlay */
.vocal-separation-overlay {
    position: absolute;
    inset: 0;
    background: rgba(10, 10, 11, 0.85);
    backdrop-filter: blur(15px);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 20px;
    z-index: 50;
    text-align: center;
    padding: 40px;
}

.vocal-separation-overlay h2 {
    font-size: 24px;
    font-weight: 800;
    color: #ffffff;
}

.vocal-separation-overlay p {
    font-size: 14px;
    color: rgba(255, 255, 255, 0.6);
    max-width: 400px;
}

/* Modals styling */
.settings-modal {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(10px);
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    /* showModal()/hideModal() in app.js toggle display:none<->flex (required so
       hidden modals don't intercept clicks) then this class for the actual
       fade+scale — display can't be transitioned, so the class is what animates. */
    opacity: 0;
    transition: opacity 0.2s ease;
}

.settings-modal.modal-open {
    opacity: 1;
}

.settings-content {
    background: rgba(20, 19, 20, 0.85);
    backdrop-filter: blur(25px);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 24px;
    width: 100%;
    max-width: 500px;
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transform: scale(0.94) translateY(8px);
    transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

.settings-modal.modal-open .settings-content {
    transform: scale(1) translateY(0);
}

/* Slider Overrides */
input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    cursor: pointer;
    width: 100%;
}

input[type="range"]:focus {
    outline: none;
}

input[type="range"]::-webkit-slider-runnable-track {
    background: transparent;
    height: 4px;
}

input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    margin-top: -4px;
    background-color: #ffffff;
    height: 12px;
    width: 12px;
    border-radius: 50%;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

/* General Layout helpers */
body {
    background-color: #0A0A0B;
    color: #e5e2e3;
    overflow: hidden;
}

main {
    scrollbar-gutter: stable;
}

/* ============================================================
   Redesign support classes (driven by JS-generated markup)
   ============================================================ */

/* Filled Material Symbols (used inline across markup) */
.fill-1 {
    font-variation-settings: 'FILL' 1;
}

/* Sidebar nav active state (blueprint: primary text, bold,
   surface-variant fill, right primary border) */
.nav-link.active {
    color: #fbfffa;
    font-weight: 700;
    background-color: #353436;
    border-right: 2px solid #00e1ab;
}

/* Compact sidebar list rows — shared by Offline Tracks + Spotify lists */
.library-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px;
    border-radius: 10px;
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.library-item:hover {
    background-color: rgba(255, 255, 255, 0.05);
}

.library-item.active {
    background-color: rgba(0, 225, 171, 0.12);
}

.library-item img {
    width: 36px;
    height: 36px;
    border-radius: 6px;
    object-fit: cover;
    flex-shrink: 0;
}

.library-item-info {
    flex: 1;
    min-width: 0;
}

.library-item-title {
    font-size: 12px;
    font-weight: 700;
    color: #e5e2e3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.library-item.active .library-item-title {
    color: #00e1ab;
}

.library-item-artist {
    font-size: 10px;
    color: #b9cbc1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Muted empty / placeholder states */
.empty-library {
    font-size: 11px;
    color: rgba(255, 255, 255, 0.35);
    text-align: center;
    padding: 16px 8px;
}

.empty-library.error {
    color: #ffb4ab;
}

/* Album/song card selection highlight (layout is Tailwind; this is the active glow) */
.song-card .card-art {
    transition: box-shadow 0.3s ease, transform 0.3s ease;
}

.song-card.active .card-art {
    box-shadow: 0 0 0 2px #00e1ab, 0 0 26px rgba(0, 225, 171, 0.28);
}

.song-card.active .card-title {
    color: #00e1ab;
}

/* Press feedback — a quick scale-down on :active so cards feel physically
   pressable instead of only reacting on release, matching Spotify's card press.
   !important beats Tailwind's arbitrary-value hover-scale utility on the same
   element, which ties this selector's specificity and would otherwise win or
   lose depending on stylesheet load order. */
.song-card:active .card-art {
    transform: scale(0.97) !important;
    transition-duration: 0.1s !important;
}

/* Spotify tracklist row interactions */
.spotify-tracklist-row {
    cursor: pointer;
    transition: background-color 0.2s ease;
}

.spotify-tracklist-row:hover {
    background-color: rgba(53, 52, 54, 0.4);
}

.spotify-tracklist-row:active {
    background-color: rgba(53, 52, 54, 0.65);
}

.spotify-tracklist-row.active {
    background-color: rgba(0, 225, 171, 0.1);
}

.spotify-tracklist-row.active .st-title {
    color: #00e1ab;
}

@keyframes fadeInSection {
    from {
        opacity: 0;
        transform: translateY(8px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Settings modal entrance */
.animate-slide-up {
    animation: slideUp 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}

/* Staggered grid/list entrance — staggerGridEntrance() in app.js adds this class to
   every card/row in a freshly-rendered grid and sets a per-item animation-delay, so
   items cascade in one after another instead of all popping in at once. `both` fill
   mode holds the "from" state during the delay so items don't flash at full opacity
   before their turn. */
.card-enter {
    animation: fadeInSection 0.35s cubic-bezier(0.4, 0, 0.2, 1) both;
}

/* Add-to-playlist confirmation pulse — briefly highlights the playlist row a track
   was just added to, on top of the existing toast, so the picker itself confirms
   which playlist received it. */
@keyframes addToPlaylistPulse {
    0% {
        background-color: rgba(0, 225, 171, 0.35);
    }

    100% {
        background-color: transparent;
    }
}

.add-to-playlist-pulse {
    animation: addToPlaylistPulse 0.6s ease-out;
}

@keyframes slideUp {
    from {
        transform: translateY(20px);
        opacity: 0;
    }

    to {
        transform: translateY(0);
        opacity: 1;
    }
}

/* Playlists grid — explicit, bulletproof auto-wrapping rectangle of compact cards */
.playlists-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 24px;
    align-items: start;
}

.playlists-grid>div {
    min-width: 0;
}

/* View-switch fade (covers tab changes, opening a playlist — any window change) */
.view-fade-out {
    opacity: 0;
    transition: opacity 0.18s ease;
}

.view-fade-in {
    animation: fadeInSection 0.32s ease;
}

/* Global browser outline resets */
input:focus,
select:focus,
textarea:focus,
button:focus {
    outline: none !important;
    box-shadow: none !important;
}

/* Shimmer animation for skeleton load cards */
@keyframes shimmer {
    0% {
        transform: translateX(-100%);
    }

    100% {
        transform: translateX(100%);
    }
}

/* Static player dock matching the sidebar's background color */
#player-dock {
    background-color: #131314 !important;
    border-top: 1px solid rgba(39, 39, 42, 0.4) !important;
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.3) !important;
}

/* Now-playing crossfade — updatePlayerNowPlaying() in app.js toggles this class
   briefly around the src/text swap so a new track's art and title fade+slide in
   instead of snapping, echoing Spotify's dock transition. */
#player-art,
#player-meta {
    transition: opacity 0.15s ease, transform 0.15s ease;
}

#player-art.now-playing-swapping {
    opacity: 0;
    transform: scale(0.96);
}

#player-meta.now-playing-swapping {
    opacity: 0;
    transform: translateY(3px);
}

/* Play/pause icon morph — a quick scale+fade pop instead of an instant glyph swap.
   No JS trigger needed: setPlayingState() toggles the two icons via display:none<->
   block, and a CSS animation never runs while display:none, so becoming visible
   always (re)starts this from 0% automatically. */
@keyframes iconPop {
    from {
        transform: scale(0.5);
        opacity: 0;
    }

    60% {
        transform: scale(1.15);
        opacity: 1;
    }

    to {
        transform: scale(1);
        opacity: 1;
    }
}

#play-icon,
#pause-icon {
    animation: iconPop 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* Now-Playing Equalizer animations */
@keyframes eq-bar-animation-1 {
    0% {
        height: 3px;
    }

    50% {
        height: 14px;
    }

    100% {
        height: 3px;
    }
}

@keyframes eq-bar-animation-2 {
    0% {
        height: 6px;
    }

    50% {
        height: 14px;
    }

    100% {
        height: 6px;
    }
}

@keyframes eq-bar-animation-3 {
    0% {
        height: 9px;
    }

    50% {
        height: 14px;
    }

    100% {
        height: 9px;
    }
}

.animate-eq-bar-1 {
    animation: eq-bar-animation-1 0.8s ease-in-out infinite;
}

.animate-eq-bar-2 {
    animation: eq-bar-animation-2 0.6s ease-in-out infinite;
}

.animate-eq-bar-3 {
    animation: eq-bar-animation-3 0.7s ease-in-out infinite;
}

/* Pause state selector mapping */
body.audio-paused .animate-eq-bar-1,
body.audio-paused .animate-eq-bar-2,
body.audio-paused .animate-eq-bar-3 {
    animation-play-state: paused !important;
}

/* EQ display on active list items */
.spotify-tracklist-row.active .index-label {
    display: none !important;
}

.spotify-tracklist-row.active .eq-icon {
    display: flex !important;
}

.spotify-tracklist-row.active:hover .eq-icon {
    display: none !important;
}

.spotify-tracklist-row.active:hover .play-icon-hover {
    display: inline-block !important;
}

/* Song card active equalizer overlay styling */
.song-card.active:hover .active-eq-overlay {
    display: none !important;
}

/* Sidebar navigation active state */
.nav-link.active {
    background-color: rgba(255, 255, 255, 0.08) !important;
    color: var(--primary) !important;
}

.nav-link.active span {
    color: var(--primary) !important;
}

/* Player dock toggle buttons (shuffle/repeat/karaoke/lyrics) — JS adds the
   "active" class on these but nothing previously styled it, so engaged modes
   were invisible once their toast faded. A filled dot echoes Spotify's
   under-icon indicator for these same toggles. */
#btn-shuffle.active,
#btn-repeat.active,
#btn-karaoke-toggle.active,
#btn-lyrics-toggle.active {
    color: var(--primary) !important;
    position: relative;
}

#btn-shuffle.active::after,
#btn-repeat.active::after,
#btn-karaoke-toggle.active::after,
#btn-lyrics-toggle.active::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: -8px;
    transform: translateX(-50%);
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background-color: var(--primary);
}

/* Prefers-reduced-motion accessibility support */
@media (prefers-reduced-motion: reduce) {

    *,
    ::before,
    ::after {
        animation-delay: -1ms !important;
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        background-attachment: initial !important;
        scroll-behavior: auto !important;
        transition-duration: 0s !important;
        transition-delay: 0s !important;
    }

    .song-card:hover .card-art,
    .song-card:active .card-art,
    .spotify-tracklist-row:hover,
    #btn-shortcuts-toggle:hover {
        transform: none !important;
        scale: none !important;
    }

    .lyric-line.active {
        transform: none !important;
    }

    .animate-pulse,
    .animate-\[shimmer_1\.5s_infinite\],
    .animate-\[shimmer_2s_infinite\] {
        animation: none !important;
    }
}

/* Redesigned Lyrics Status Pill */
#lyric-status-pill {
    position: relative;
    box-sizing: border-box;
    transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1),
                background-color 0.3s ease,
                border-color 0.3s ease,
                color 0.3s ease;
    overflow: hidden;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 24px;
}

/* Svg border container */
.lyric-pill-svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    overflow: visible; /* Prevents drop-shadow glow clipping */
}

.lyric-pill-rect {
    fill: none;
    stroke: transparent;
    stroke-width: 1.5;
    transition: stroke 0.4s ease, stroke-dashoffset 0.3s linear;
}

/* Glowing white progress border */
.lyric-pill-rect.syncing {
    stroke: #ffffff;
    filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.95)) drop-shadow(0 0 1px rgba(255, 255, 255, 0.6));
}

/* Immersive Now Playing View layout overrides for xl breakpoint */
@media (min-width: 1280px) {
    #lyrics-view-container {
        display: flex !important;
        flex-direction: row !important;
    }
    
    #album-art-column {
        width: 12.5% !important; /* 25% smaller than the original 16.66% width */
        flex-shrink: 0 !important;
    }
    
    #lyrics-column {
        flex: 1 !important;
        min-width: 0 !important;
    }
    
    .lyrics-wrapper {
        padding-left: 3rem !important; /* Elegant spacing to prevent scaled lyrics from clipping */
    }
    
    #queue-container {
        width: 18.75% !important; /* 25% smaller than the original 25% width (col-span-3) */
        flex-shrink: 0 !important;
        transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1), 
                    opacity 0.25s ease, 
                    margin-left 0.35s cubic-bezier(0.4, 0, 0.2, 1);
        display: flex !important;
        overflow: hidden;
    }
    
    #lyrics-view-container.queue-collapsed #queue-container {
        width: 0 !important;
        opacity: 0 !important;
        margin-left: -32px !important; /* overrides grid/flex gap spacing when collapsed */
        pointer-events: none !important;
    }
}

/* Ensure the queue collapse button is always clickable above transitioned panels */
#btn-toggle-queue {
    position: relative;
    z-index: 50;
}

/* Collapsible "Add Songs" panel on the local playlist view — same collapse
   mechanics as the Up Next queue panel (#queue-container above): width +
   opacity + margin transition with overflow hidden, toggled by a class on
   the shared flex parent. Starts collapsed (width 0) so an untouched local
   playlist looks identical to the Spotify playlist view. */
#local-playlist-add-panel {
    width: 0;
    flex-shrink: 0;
    opacity: 0;
    overflow: hidden;
    margin-left: -32px; /* cancels the gap-8 (2rem) parent gap while collapsed */
    transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1),
                opacity 0.25s ease,
                margin-left 0.35s cubic-bezier(0.4, 0, 0.2, 1);
    pointer-events: none;
}

#local-playlist-layout.add-panel-open #local-playlist-add-panel {
    width: 380px;
    opacity: 1;
    margin-left: 0;
    pointer-events: auto;
}

/* Below this width, sharing flex space with a fixed 380px panel would squeeze
   the header (art + gradient title) unreadably — the app's enforced minimum
   window is 960x600 (see launcher.py's create_window min_size), well under
   here. The Up Next queue panel sidesteps this by only existing at xl
   (1280px+) and hiding outright below that; "Add Songs" is core playlist
   functionality rather than a nice-to-have, so instead of hiding it, it
   becomes a fixed overlay drawer that slides in from the right edge without
   taking any space away from the main column. */
@media (max-width: 1023px) {
    #local-playlist-add-panel {
        position: fixed;
        top: 0;
        right: 0;
        width: min(380px, 90vw);
        height: 100vh;
        margin-left: 0;
        opacity: 1;
        transform: translateX(100%);
        transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
        z-index: 60;
        box-shadow: -20px 0 60px rgba(0, 0, 0, 0.5);
    }

    #local-playlist-layout.add-panel-open #local-playlist-add-panel {
        width: min(380px, 90vw);
        margin-left: 0;
        transform: translateX(0);
    }
}