/* music-player.css — bottom .ms-player bar (transport,
   marquee scaffolding, seek + volume sliders, modifier
   buttons, the .mpb-btn-flash press animation, the
   .mpb-pulse autoplay-blocked nudge). */

/* ===================== Player bar =====================
   DESKTOP: three equal columns (1fr / 1fr / 1fr). This is the only
   layout that gets transport sitting at the PLAYER's true horizontal
   centre while also clipping a long title at a predictable left-third
   boundary — asymmetric column widths drift the centre cluster off
   centre by the column-width difference.

     row 1:  [track 1fr]   [transport / timeline 1fr]   [right 1fr]

   Track sticks to col-1's left edge (default justify-self: stretch).
   Right cluster pins to col-3's right edge via justify-self: end so
   modifiers always hit the player's right edge regardless of col width.
   The empty space inside col-3 between transport and the modifier
   cluster is intentional — it preserves transport's centring.

   MOBILE override (≤720px) flips .mpb-controls to display:contents so
   the seek bar lifts into its own full-width row 2 underneath. */
.ms-player {
    grid-area: player;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: auto;
    grid-template-areas: "track controls right";
    align-items: center;
    column-gap: 1.5rem;       /* between-cluster gap — ≥3× the within-cluster 0.4rem */
    padding: 0.55rem 1rem;
    border-top: 1px solid var(--panel-border);
    /* Pure --bg (not --panel-bg) so the player bar blends with the page
       background — one continuous black band rather than a slightly-
       elevated panel sitting on top. Same treatment on the sidebar +
       queue panel + mini-player; the border-top keeps the visual
       separation. */
    background: var(--bg);
    transition: background var(--dur-fast) var(--ease-smooth), border-color var(--dur-fast) var(--ease-smooth);
    z-index: 20;
}
.mpb-track {
    grid-area: track;
    min-width: 0;
    overflow: hidden;
}
.mpb-right {
    grid-area: right;
    justify-self: end;        /* pin modifier cluster to col-3's right edge */
}

/* Centre cluster: transport above seek. Centered within col-2 so even on
   wide displays the cluster sits at the visual middle, not the left
   edge of the column. */
.mpb-controls {
    grid-area: controls;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-self: center;
    gap: 0.4rem;
    min-width: 0;
    width: 100%;              /* let the seek bar grow up to its max-width */
}
/* Idle state: keep the same layout as when a track is playing so the
   player chrome doesn't reshape between empty / playing — only dim the
   visual weight. Cover stays as an empty 48 × 48 slot (its background
   is var(--row-hover), so an empty .mpb-cover with no <img>/<svg>
   child renders as a dimmed square placeholder). Title + artist lines
   keep their height with empty marquee text. Seek strip stays at full
   height but goes opacity-dim + pointer-events-none. */
.ms-player[data-loaded="false"] .mpb-title  { color: var(--fg-dim); }
.ms-player[data-loaded="false"] .mpb-artist { color: var(--fg-dim); }
.ms-player[data-loaded="false"] .mpb-cover  { opacity: 0.45; }
.ms-player[data-loaded="false"] .mpb-seek   { opacity: 0.45; pointer-events: none; }

.mpb-track {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
}
.mpb-cover {
    width: 48px;
    height: 48px;
    border-radius: 4px;
    overflow: hidden;
    background: var(--row-hover);
    flex-shrink: 0;
    box-shadow: var(--shadow-sm);
}
.mpb-cover img,
.mpb-cover svg {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.mpb-meta {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    flex: 1 1 0;
    /* Hard cap on the title/artist visible width. The grid column is 1fr
       (~33% of the player) which on wide displays is 700-900px — way more
       than any title needs and prevents the marquee from ever overflowing.
       Capping here forces overflow at typical desktop widths so long
       titles + artist names actually scroll. */
    max-width: 240px;
}
.mpb-title,
.mpb-artist {
    text-align: left;
    background: none;
    border: none;
    color: inherit;
    cursor: pointer;
    padding: 0;
    /* No ellipsis — long titles clip at the container edge and the JS
       marquee scrolls them. Text-overflow ellipsis used to live here. */
    overflow: hidden;
    max-width: 100%;
    width: 100%;
    display: block;
}

/* Marquee scaffolding. Two copies of the text live inside
   .mpb-marquee-inner; the duplicate is hidden by default so a
   non-overflowing title doesn't render twice. When the text DOES
   overflow the title/artist column, music-core.js adds .marquee-scroll
   to the outer .mpb-title / .mpb-artist (which un-hides the
   duplicate) and applies an `animation` to .mpb-marquee-inner that
   translates it left by `textWidth + MARQUEE_GAP` continuously —
   the second copy ends up exactly where the first started, so the
   loop has no visible snap. */
.mpb-marquee-inner {
    display: inline-block;
    white-space: nowrap;
    will-change: transform;
}
.mpb-marquee-text { display: inline-block; }
/* Duplicate sits to the right of the first copy with MARQUEE_GAP
   between them. Kept hidden until the marquee activates so the
   non-overflowing case shows the title once, not twice. The 24 px
   gap must match the JS MARQUEE_GAP constant in music-core.js —
   tuned together; if you change one, change both. */
.mpb-marquee-text-dup {
    display: none;
    margin-left: 24px;
}
.marquee-scroll .mpb-marquee-text-dup {
    display: inline-block;
}

/* Pause the scroll while the user is hovering the title/artist, so they
   can read the full text without it sliding out from under them. */
.mpb-title:hover .mpb-marquee-inner,
.mpb-artist:hover .mpb-marquee-inner {
    animation-play-state: paused;
}
.mpb-title {
    font-size: 1rem;
    line-height: 1.25;
    color: var(--fg);
    font-weight: 700;
}
.mpb-artist {
    font-size: var(--text-xs);
    line-height: 1.15;
    font-weight: 400;
    color: var(--fg-dim);
    letter-spacing: 0.02em;
    opacity: 0.85;
}
.mpb-title:hover,
.mpb-artist:hover { color: var(--accent); }
.mpb-title[aria-disabled="true"],
.mpb-artist[aria-disabled="true"] { cursor: default; }
.mpb-title[aria-disabled="true"]:hover,
.mpb-artist[aria-disabled="true"]:hover { color: inherit; }

/* .mpb-controls used to be a flex-column wrapper around buttons + seek.
   With the new player layout each child has its own grid-area, so .mpb-
   controls collapses via `display: contents` (set above on .ms-player). */
.mpb-buttons {
    display: flex;
    align-items: center;
    gap: 0.4rem;             /* within-cluster gap */
    flex-shrink: 0;          /* never get squeezed by a long title */
}
/* All "modifier" buttons (prev / next / shuffle / repeat / volume-icon /
   queue-btn) — 22×22 circle. Play/pause stays larger (32×32) so it reads
   as the primary action. */
.mpb-btn {
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--fg-muted);
    border-radius: 50%;
    position: relative;        /* anchor the active-state dot below */
    transition: color var(--dur-fast) var(--ease-smooth), background var(--dur-fast) var(--ease-smooth), transform var(--dur-fast) var(--ease-smooth);
}
.mpb-btn:hover { color: var(--fg); background: var(--btn-bg-hover); }
.mpb-btn[aria-pressed="true"] { color: var(--accent); }
/* Active-state indicator: tiny accent dot below shuffle / repeat when on.
   Disambiguates `repeat=off` from `repeat=all` (both use #i-repeat — only
   the dot + accent color tell you the loop is engaged). */
.mpb-btn[aria-pressed="true"]::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: -4px;
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--accent);
    transform: translateX(-50%);
}

/* Click feedback: brief press scale + an accent-color flash on the icon.
   `:active` covers the moment the mouse/touch is held down; `.is-pressed`
   is toggled in music.js so the flash runs on click regardless of how
   short the press was. Both restore to baseline via the existing
   .mpb-btn transition. */
.mpb-btn:active { transform: scale(0.88); }
.mpb-btn-primary:active { transform: scale(0.92); }
.mpb-btn.is-pressed .icon {
    animation: mpb-btn-flash var(--dur-fast) var(--ease-quick);
}
@keyframes mpb-btn-flash {
    0%   { color: var(--accent); filter: brightness(1.6); }
    100% { filter: brightness(1); }
}

/* Pulse ring used to draw the eye to the play button when arriving on
   /musiced#resume and iOS Safari has refused the auto-play. Three
   outward ripples + a tiny scale bump per cycle. JS adds .mpb-pulse
   on arrival and self-removes the class after ~5 s. */
@keyframes mpb-pulse {
    0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 70%, transparent); transform: scale(1); }
    70%  { box-shadow: 0 0 0 14px color-mix(in srgb, var(--accent) 0%, transparent); transform: scale(1.08); }
    100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent); transform: scale(1); }
}
.mpb-pulse {
    animation: mpb-pulse 1.4s ease-out 3;
}
/* Play / pause — cyan accent surface, larger than the modifier buttons so
   it visually anchors the transport cluster. */
.mpb-btn-primary {
    background: var(--accent);
    color: var(--bg);
    width: 32px;
    height: 32px;
}
.mpb-btn-primary:hover {
    background: color-mix(in srgb, var(--accent) 80%, var(--fg));
    color: var(--bg);
    transform: scale(1.06);
}

.mpb-seek {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
    /* Bumped from 640 → 900 so the timeline gets visible real estate on
       desktop. Still capped to prevent silly-long bars on 4K monitors. */
    max-width: 900px;
    justify-self: center;
}
.mpb-time {
    font-size: var(--text-xs);
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
    min-width: 3.2ch;
    text-align: center;
}

.mpb-right {
    display: flex;
    align-items: center;
    gap: 0.4rem;             /* within-cluster gap — matches .mpb-buttons */
    flex-shrink: 0;          /* protected from long-title squeeze */
}
/* Pin to a fixed width. Selector chained through input[type=range] so it
   beats `.music-app input[type=range] { flex: 1; min-width: 60px }` on
   specificity — otherwise the slider stretches to fill .mpb-right. */
.music-app input[type=range].mpb-vol-slider {
    flex: 0 0 90px;
    width: 90px;
    min-width: 90px;
    max-width: 90px;
}
.mpb-vol-pct {
    font-size: var(--text-xs);
    color: var(--fg-muted);
    font-variant-numeric: tabular-nums;
    min-width: 3.5ch;          /* 3 digits + % */
    text-align: right;
    user-select: none;
}

/* Mobile nav pill — hidden on desktop. The full mobile styling
   (segments, active accent, sizing) lives in music-mobile.css under
   the same @media (max-width: 720px) that opens the pill via
   display: inline-flex. Explicit @media (min-width: 721px) wrap +
   !important is belt-and-braces: ensures the pill is invisible at
   desktop widths no matter what cascade comes later. */
.mpb-nav-pill { display: none; }
@media (min-width: 721px) {
    .mpb-nav-pill { display: none !important; }
}


/* Mobile-only floating timestamp bubble — hidden on desktop. Lives
   inside .mpb-seek for positioning; .mpb-seek itself is desktop's
   timeline strip and stays unaffected. */
.mpb-progress-bubble { display: none; }

/* Range sliders — flat dark */
.music-app input[type=range] {
    -webkit-appearance: none;
    appearance: none;
    height: 4px;
    background: var(--panel-border);
    border-radius: 2px;
    outline: none;
    cursor: pointer;
    flex: 1;
    min-width: 60px;
}
.music-app input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--accent);
    cursor: pointer;
    border: none;
}
.music-app input[type=range]::-moz-range-thumb {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--accent);
    cursor: pointer;
    border: none;
}


