/* music-topbar.css — .ms-topbar, the search input wrapper,
   per-view extras (.ms-topbar-extra w/ specificity-bumped
   hide rule), the .ms-mode-toggle (grid/list), the select
   mode action bar, .ms-view-entering fade. */

/* ===================== Main ===================== */
.ms-main {
    grid-area: main;
    /* Flex column with .ms-view as the scrolling child (not .ms-main
       itself). Lets the topbar sit naturally above the scroll context
       — no `position: sticky` needed, and no iOS Safari sticky-in-
       scroll-container quirks. */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
    position: relative;
    background: var(--bg);
}

/* The topbar (search + mode toggle + Add music/folder + Select) is a
   library-only surface. Now shows on EVERY view (library, playlists,
   playlist:<id>, search) so all four pages' search inputs + titles
   line up at the same Y coordinate. Per-view rules below hide the
   topbar items that don't apply to each view. */

/* Single-playlist view: shows the full topbar-actions cluster
   (grid/list toggle, Add music, Add folder, Select) just like
   library, so the row is consistent across both. The grid/list
   toggle drives state.libraryMode for both views (renderPlaylist
   honors it); Add music / Add folder import into the library —
   the imported tracks aren't auto-added to the playlist (drag
   them in from library if you want that). */

/* On the search aggregator view, the topbar gathers everything into a
   single row: the per-view title slot ("Search"), the search input,
   and the Get Musiced Desktop link. The in-page header still renders
   its own h1 + <label class="ms-discover-search">, hidden here so
   they don't render twice. Topbar actions (grid/list toggle, Add
   music, Add folder, Select) don't apply to remote search results,
   so hide those too. */
.music-app[data-view="search"] .ms-topbar-actions,
.music-app[data-view="search"] .ms-discover-head .ms-discover-search,
.music-app[data-view="search"] .ms-discover-head h1 {
    display: none;
}

/* Per-view topbar slots — title on the left, extra action on the right.
   Hidden by default; views opt in via the rules below. The title font-
   size + weight are shared across every view (library / playlist /
   search) so the three pages read as a consistent set. Long playlist
   names get ellipsized rather than pushing the search input narrow.

   No reserved min-width slot — the title sits at its natural text
   width with just the 1rem column gap before the search input. The
   alignment of the search input's RIGHT edge across views is handled
   by removing `max-width` on `.ms-search-wrap` below, so the search
   input grows to fill whatever space sits between the title and the
   right-side extra (which is itself the same width across Playlists
   and Search via `min-width: 11rem`).

   `line-height: 1` locks vertical metrics regardless of font-rendering
   nuances so the title text never appears taller/heavier on one view
   than another. Specificity is bumped via `.music-app` so any future
   per-view selector can't silently win the size/weight battle. */
.music-app .ms-topbar-title {
    margin: 0;
    font-family: var(--font-mono) !important;
    font-size: 1.05rem !important;
    font-weight: 700 !important;
    font-style: normal !important;
    line-height: 1 !important;
    color: var(--fg);
    letter-spacing: 0.01em;
    flex-shrink: 1;
    flex-grow: 0;
    min-width: 0;
    max-width: 28ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: none;
}
/* Specificity-bumped via `.music-app` ancestor so this rule beats the
   bare `.ms-btn { display: inline-flex; }` declared later in the file
   — without it, the New playlist <button class="ms-btn …"> shows on
   every view with a topbar, not just /playlists. The per-view reveal
   rules below (e.g. `.music-app[data-view="playlists"] .ms-…`) carry
   even higher specificity, so they still flip the default to visible. */
.music-app .ms-topbar-extra { display: none; }

/* Views that show the topbar title: library, playlists grid, single
   playlist, search. inline-flex + align-items: center keeps the text
   vertically centered in the 32 px control row so it baseline-aligns
   with the search input / extras / topbar buttons.

   Wrapped in `min-width: 721px` so the title only ever shows on
   desktop. Mobile-first inversion (mirrors the sidebar fix in
   music-sidebar.css) avoids the iOS Safari initial-load race where
   the title flashed at desktop size before the mobile `display: none`
   override applied. */
@media (min-width: 721px) {
    .music-app[data-view="library"] .ms-topbar-title,
    .music-app[data-view="playlists"] .ms-topbar-title,
    .music-app[data-view^="playlist:"] .ms-topbar-title,
    .music-app[data-view="search"] .ms-topbar-title {
        display: inline-flex;
        align-items: center;
    }
}

/* Playlists grid: hide the library-specific topbar-actions (grid mode
   toggle, Add music, Add folder, Select aren't meaningful here) and
   reveal the New playlist extra. `min-width: 11rem` makes this button
   exactly as wide as the search-view `.ms-topbar-get-musiced` link
   below — the two right-side single-button extras read as one
   consistent slot across views. */
.music-app[data-view="playlists"] .ms-topbar-actions { display: none; }
.music-app[data-view="playlists"] .ms-topbar-new-playlist {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-width: 11rem;
    flex-shrink: 0;
}

/* Search view also reveals the Get Musiced link. Styled to share the
   topbar's 32 px control row — cyan outline rounded rectangle that
   fills on hover. Matches the unified 6 px corner radius used by
   every interactive element on the site. `min-width: 11rem` matches
   the playlists-view "New playlist" button above so the two views'
   right-side extras occupy the same horizontal slot. */
.music-app[data-view="search"] .ms-topbar-get-musiced {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    height: var(--control-h);
    box-sizing: border-box;
    padding: 0 0.85rem;
    min-width: 11rem;
    border: 1px solid var(--accent);
    border-radius: 6px;
    background: transparent;
    color: var(--accent);
    font-size: 0.78rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    flex-shrink: 0;
    transition: background var(--dur-fast) var(--ease-smooth),
                color var(--dur-fast) var(--ease-smooth);
}
.music-app[data-view="search"] .ms-topbar-get-musiced:hover {
    background: var(--accent);
    color: var(--bg);
}
.music-app[data-view="search"] .ms-topbar-get-musiced .icon {
    width: 13px;
    height: 13px;
}

.ms-topbar {
    /* Lives in .ms-main flex flow above the scrollable .ms-view, so it
       naturally stays pinned without `position: sticky` (which was
       unreliable inside iOS Safari's overflow:auto contexts). */
    flex-shrink: 0;
    z-index: 10;
    padding: 1rem 2rem 0.85rem;
    background-color: var(--bg);
    display: flex;
    align-items: center;
    gap: 1rem;
}
.ms-topbar-actions {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}
.ms-search-wrap {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: var(--panel-bg);
    border: 1px solid var(--panel-border);
    border-radius: 6px;
    /* Equal-height-in-row rule — see .ms-btn note above. */
    height: var(--control-h);
    box-sizing: border-box;
    padding: 0 1rem;
    /* `flex: 1` with NO max-width: the search input fills whatever
       horizontal space sits between the title and the right-side
       extra. Because `.ms-topbar-actions`, `.ms-topbar-new-playlist`,
       and `.ms-topbar-get-musiced` are anchored to the topbar's right
       edge (the actions cluster via `margin-left: auto`, the single
       buttons via `min-width: 11rem` + their natural placement after
       a flex-grown search input), the search input's RIGHT edge sits
       at `container-right − right-extra-width − gap` — i.e. the same
       X on Playlists and Search (both have 11rem extras) regardless
       of title length. Library's extra is naturally wider (multi-
       button cluster) so its search ends earlier, but that's the
       cost of having a real action cluster instead of one button. */
    flex: 1;
    transition: border-color var(--dur-fast) var(--ease-smooth), background var(--dur-fast) var(--ease-smooth);
}
.ms-search-wrap:focus-within {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 4%, var(--panel-bg));
}
.ms-search-wrap .icon { color: var(--fg-muted); }
.ms-search-input {
    flex: 1;
    background: transparent;
    border: none;
    color: var(--fg);
    font: inherit;
    font-size: var(--text-sm);
    outline: none;
}
.ms-search-input::placeholder { color: var(--fg-dim); }

.ms-view {
    padding: 0.25rem 2rem 2rem;
    outline: none;
    display: flex;
    flex-direction: column;
    /* .ms-view is the actual scroll container (not .ms-main). Topbar
       above stays pinned because it's outside this overflow. */
    flex: 1;
    overflow-y: auto;
    min-height: 0;
}

/* View-switch fade. goto() adds .ms-view-entering on every nav, forces
   a reflow, then removes it ~220 ms later. The animation runs on the
   view's direct children rather than .ms-view itself because the view
   is also the scroll container — fading the container would briefly
   distort scroll-position math while opacity transitioned. Children
   fade together as a content block. */
@keyframes ms-view-enter {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}
.ms-view-entering > * {
    animation: ms-view-enter 200ms var(--ease-smooth);
}


