/* ═══════════════════════════════════════════════════════════════════════
   Library.css — the fake music import.

   Drag the Music folder off the desktop onto the myPod window and the right
   panel runs the app's real import sequence in miniature: progress popup,
   then the song list and search bar. It exists to show a visitor what the
   tool actually does, so every number here is measured from the same Swift
   source as Window.css — SongsPanelView.swift this time.

   Kept out of Window.css deliberately: that file is the static replica, this
   one is the interaction. Nothing in here runs until someone drags.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Dragging the Music folder ──────────────────────────────────────────
   Pointer Events, not HTML5 drag-and-drop. The native API insists on its
   own drag image (a washed-out screenshot of the element, positioned by the
   browser), fires no move events on some platforms, and can't be styled —
   none of which suits a fake macOS desktop. Pointer events also give touch
   support for free.
   ───────────────────────────────────────────────────────────────────── */
.DesktopIcon[data-drag-source]{ cursor: grab; }
.DesktopIcon[data-drag-source]:active{ cursor: grabbing; }

/* Finder dims the original while a copy follows the cursor — the folder
   isn't going anywhere, it's being copied from. */
.DesktopIcon.is-dragging{ opacity: .35; }

.DragGhost{
  position: fixed;
  top: 0; left: 0;
  width: 84px;
  z-index: var(--z-drag);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  opacity: .85;
  pointer-events: none;                 /* never eats the drop it's causing */
  cursor: grabbing;
}
.DragGhost img{
  width: 64px; height: 64px;
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.4));
}
.DragGhost .DesktopIcon-label{
  font-size: 12px;
  color: #fff;
  padding: 1px 5px;
  border-radius: 4px;
  text-shadow: 0 1px 3px rgba(0,0,0,.5);
}
/* Springing home after a miss. Added only for that trip, so the ghost still
   tracks the cursor with zero lag while it's actually being dragged. */
.DragGhost.is-returning{
  transition: transform .28s cubic-bezier(.2,.7,.3,1), opacity .28s ease;
  opacity: 0;
}

/* Drop target. The app strokes the panel — not the whole window — at
   cornerRadius 10, accent colour at 50%, 2pt. */
.Window-panel::after{
  content: '';
  position: absolute;
  inset: 0 16px;
  border: 2px solid rgba(0,122,255,0);
  border-radius: 10px;
  pointer-events: none;
  transition: border-color .15s ease;
}
.Window.is-dropTarget .Window-panel::after{ border-color: rgba(0,122,255,.5); }


/* ── Panel states ───────────────────────────────────────────────────────
   Empty state, import popup and library all occupy the same space and
   cross-fade. `visibility` rides along with opacity so a faded-out layer
   can't swallow a hover or a scroll.
   ───────────────────────────────────────────────────────────────────── */
.EmptyState,
.Library,
.ImportPopup{
  transition: opacity .25s ease, visibility .25s;
}
.Library,
.ImportPopup{
  opacity: 0;
  visibility: hidden;
}
.Window-panel.is-importing .EmptyState{ opacity: 0; visibility: hidden; }
.Window-panel.is-importing .ImportPopup{ opacity: 1; visibility: visible; }
.Window-panel.has-library  .EmptyState{ opacity: 0; visibility: hidden; }
.Window-panel.has-library  .Library   { opacity: 1; visibility: visible; }


/* ── Import progress popup ──────────────────────────────────────────── */
.ImportPopup{
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: 200px;                         /* frame(maxWidth: 200) */
  padding: 18px 20px;
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  /* .glassEffect(.regular) — same recipe as the Restore pill. */
  background: rgba(255,255,255,.46);
  -webkit-backdrop-filter: blur(22px) saturate(180%) brightness(1.06);
          backdrop-filter: blur(22px) saturate(180%) brightness(1.06);
  box-shadow:
    inset 0 .5px 0 rgba(255,255,255,.9),
    inset 0 0 0 .5px rgba(255,255,255,.5);
}
.ImportPopup-title{
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-50);
}
.ImportPopup-count{
  margin-top: 3px;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-25);
  font-variant-numeric: tabular-nums;    /* no width jitter as it counts */
}

/* NSProgressIndicator. steps(8), not a linear sweep — the real spinner
   advances one spoke at a time. */
.Spinner{
  width: 20px; height: 20px;
  fill: rgba(0,0,0,.55);
}
.Spinner-spokes{
  transform-origin: 50% 50%;
  animation: Spinner-rotate .8s steps(8, end) infinite;
}
@keyframes Spinner-rotate{ to{ transform: rotate(360deg); } }


/* ── The library ────────────────────────────────────────────────────────
   Panel content is 230 wide (262 − 2×16), same as the app's frame(width:230).
   ───────────────────────────────────────────────────────────────────── */
.Library{
  position: absolute;
  inset: 0 16px;
}

/* The 66px head and 100px tail are the app's Color.clear spacers: the head
   clears the segmented control, the tail keeps the last row from hiding
   under the search bar. */
.Library-scroll{
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 66px 10px 100px;
  scrollbar-width: none;                /* showsIndicators: false */
  overscroll-behavior: contain;
  /* Fades top and bottom. Painted against the border box, so it stays put
     while the content scrolls under it. */
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0, #000 100px, #000 calc(100% - 100px), transparent 100%);
          mask-image: linear-gradient(to bottom,
    transparent 0, #000 100px, #000 calc(100% - 100px), transparent 100%);
}
.Library-scroll::-webkit-scrollbar{ display: none; }

/* ── One song row ───────────────────────────────────────────────────────
   ⚠️ No mix-blend-mode on these, unlike the rest of the panel text. The
   scroller's mask isolates its subtree, so a blend inside it would compose
   against nothing instead of against the window glass — the effect is lost
   and the cost is a repaint per scrolled frame across every row.
   ───────────────────────────────────────────────────────────────────── */
.Song{
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
  font-size: 10px;
  font-weight: 500;
}
/* Hover fill bleeds 8px past the row on both sides, so it lines up with the
   panel's inner edge rather than the text. */
.Song::before{
  content: '';
  position: absolute;
  inset: 0 -8px;
  border-radius: 6px;
  background: rgba(0,0,0,0);
  transition: background .15s ease;
}
.Song:hover::before{ background: rgba(0,0,0,.05); }

.Song::after{
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 1px;
  background: var(--ink-10);
}

/* Both columns truncate: the title takes the slack, the artist is a fixed
   60px. min-width:0 is what actually lets a flex child shrink far enough to
   ellipsis — without it the row just overflows. */
.Song-title,
.Song-artist{
  position: relative;                   /* above the hover fill */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.Song-title{
  flex: 1 1 auto;
  min-width: 0;
  color: var(--ink-50);
}
.Song-artist{
  flex: 0 0 60px;
  width: 60px;
  color: var(--ink-25);
}


/* ── Search bar ─────────────────────────────────────────────────────────
   Decorative: there's nothing to search that a visitor hasn't just watched
   arrive. It's a <span>, not an <input>, so nobody types into a dead field.
   ───────────────────────────────────────────────────────────────────── */
.SearchBar{
  position: absolute;
  left: 0; right: 0; bottom: 20px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  background: rgba(255,255,255,.46);
  -webkit-backdrop-filter: blur(22px) saturate(180%) brightness(1.06);
          backdrop-filter: blur(22px) saturate(180%) brightness(1.06);
  box-shadow:
    inset 0 .5px 0 rgba(255,255,255,.9),
    inset 0 0 0 .5px rgba(255,255,255,.5);
}
.SearchBar-icon{
  width: 12px; height: 12px;
  flex: none;
  color: var(--ink-50);
}
.SearchBar-text{ color: var(--ink-25); }


/* ── Reduced motion ─────────────────────────────────────────────────────
   The drag itself is the interaction and stays. What goes is the spinning
   and the cross-fades — decoration on top of it.
   ───────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce){
  .Spinner-spokes{ animation: none; }
  .DragGhost.is-returning{ transition: none; }
  .EmptyState,
  .Library,
  .ImportPopup{ transition: none; }
}
