/* ══════════════════════════════════════════════════════════════════════════
   Library Cover Flow — 웹앱판
   데스크톱 확장(coverflow.js)의 CSS를 가져와 터치 화면에 맞게 고친 것이다.

   확장판과 다른 점
   · 오버레이가 아니라 페이지 전체다 (덮을 Spotify UI 가 없다)
   · macOS 신호등 버튼 회피용 padding-top 46px 이 없다. 대신 노치 안전영역을 쓴다
   · 세로 화면에서 커버가 화면 폭을 더 쓰고, 뒷면 글자와 터치 영역이 크다
   ══════════════════════════════════════════════════════════════════════════ */

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0; height: 100%;
  background: #000; color: #fff;
  overscroll-behavior: none;            /* 당겨서 새로고침 방지 */
  -webkit-tap-highlight-color: transparent;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo",
               "Noto Sans KR", "Segoe UI", Roboto, sans-serif;
  user-select: none; -webkit-user-select: none;
}

button, input { font-family: inherit; }
button:focus:not(:focus-visible) { outline: none; }

#cf-app {
  position: fixed; inset: 0;
  display: none; flex-direction: column;
  overflow: hidden;
  height: 100dvh;                       /* 사파리 주소창 높이 변화 대응 */
  --cf-flip: 2;                         /* 뒤집었을 때 배율 — JS가 갱신 */
}
#cf-app.cf-on { display: flex; }

/* ── 배경 ────────────────────────────────────────────────────────────────
   앨범 대표색을 크게 번지게 깔고, 가장자리만 눌러 준다.                    */
#cf-ambient {
  position: absolute; inset: 0; pointer-events: none;
  filter: blur(100px) saturate(1.55); opacity: .58;
  transition: background 700ms ease;
}
#cf-vignette {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at 50% 40%, transparent 36%, rgba(0,0,0,.88) 100%);
}

/* ── 상단 바 ─────────────────────────────────────────────────────────────*/
#cf-top {
  position: relative; z-index: 5;
  display: flex; align-items: center; gap: 8px;
  padding: calc(env(safe-area-inset-top, 0px) + 10px) 12px 8px;
}
#cf-search {
  flex: 1 1 auto; min-width: 0;
  background: rgba(255,255,255,.09); border: 1px solid transparent; color: #fff;
  border-radius: 500px; padding: 10px 14px; font-size: 15px; outline: none;
  transition: background .15s, border-color .15s;
}
#cf-search::placeholder { color: #8a8a8a; }
#cf-search:focus { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.25); }

.cf-chip {
  flex: 0 0 auto; white-space: nowrap;
  background: rgba(255,255,255,.09); border: 0; color: #ddd; cursor: pointer;
  border-radius: 500px; padding: 10px 14px; font-size: 13px;
  transition: background .15s, color .15s;
}
.cf-chip:hover { background: rgba(255,255,255,.18); color: #fff; }
.cf-chip.cf-warn { background: rgba(255,170,60,.18); color: #ffb84d; }

#cf-count {
  font-size: 12px; color: #8a8a8a; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ── 무대 ────────────────────────────────────────────────────────────────
   반사가 아래로 뻗으므로 padding-bottom 으로 커버를 위로 올려둔다.        */
#cf-stage {
  position: relative; z-index: 2; flex: 1 1 auto;
  display: flex; align-items: center; justify-content: center;
  /* 반사가 아래로 뻗는 만큼 커버를 위로 올려둔다.
     --cf-pad 는 JS의 #metrics() 가 화면 높이에 따라 정한다 (짧은 화면은 거의 0). */
  padding-bottom: calc(var(--cf-size) * var(--cf-pad, 0.46));
  perspective: 1400px; perspective-origin: 50% 42%;
  touch-action: none;                   /* 스와이프가 페이지 스크롤로 새지 않게 */
  cursor: grab;
}
#cf-stage.cf-drag { cursor: grabbing; }
#cf-track {
  position: relative; width: 100%; height: var(--cf-size);
  transform-style: preserve-3d;
}

.cf-item {
  position: absolute; top: 50%; left: 50%;
  width: var(--cf-size); height: var(--cf-size);
  margin: calc(var(--cf-size)/-2) 0 0 calc(var(--cf-size)/-2);
  transform-style: preserve-3d;
  transition: transform 520ms cubic-bezier(.22,.68,.36,1), opacity 420ms ease, filter 420ms ease;
  /* will-change: transform 을 쓰지 말 것 — 앨범 수만큼 합성 레이어가 생겨
     오히려 프레임이 튄다. 확장판에서 171장으로 실측해 확인한 사항이다. */
}

/* 앞/뒤 두 면을 가진 뒤집기 컨테이너 */
.cf-flip {
  position: absolute; inset: 0;
  transform-style: preserve-3d;
  transition: transform 640ms cubic-bezier(.2,.7,.3,1);
}
.cf-item.cf-flipped .cf-flip { transform: rotateY(180deg); }

.cf-face {
  position: absolute; inset: 0; border-radius: 6px; overflow: hidden;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  box-shadow: 0 30px 62px rgba(0,0,0,.82), 0 8px 18px rgba(0,0,0,.6);
}
.cf-art { background: #1a1a1a center/cover no-repeat; cursor: pointer; }
.cf-art::after {                        /* 유리 반사광 */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, rgba(255,255,255,.24) 0%, rgba(255,255,255,.05) 34%, transparent 56%);
}
.cf-item.cf-active .cf-face {
  box-shadow: 0 46px 100px rgba(0,0,0,.92), 0 14px 32px rgba(0,0,0,.72),
              0 0 0 1px rgba(255,255,255,.15),
              0 26px 96px -26px var(--cf-glow, rgba(255,255,255,.55));
}

/* 검은 배경에서는 검은 그림자가 보이지 않는다. 그래서 세 겹으로 입체감을 만든다.
   DOM 순서가 중요하다: .cf-glow → .cf-flip → .cf-reflect → .cf-shadow
   (preserve-3d 안에서는 z-index 가 기대대로 동작하지 않는다) */
.cf-glow {
  position: absolute; left: 50%; top: 80%;
  width: 195%; height: 66%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at center,
              var(--cf-glow, rgba(255,255,255,.28)) 0%, transparent 70%);
  filter: blur(40px); opacity: .1; pointer-events: none;
  transition: opacity 520ms ease;
}
.cf-item.cf-active .cf-glow { opacity: .82; }

.cf-shadow {
  position: absolute; left: 50%; top: 99%;
  width: 118%; height: 19%;
  transform: translateX(-50%);
  background: radial-gradient(ellipse at center top,
              rgba(0,0,0,.96) 0%, rgba(0,0,0,.66) 32%,
              rgba(0,0,0,.24) 58%, transparent 80%);
  filter: blur(9px); pointer-events: none;
  transition: opacity 420ms ease;
}

/* 거울 반사 — scaleY(-1) 로 뒤집는다.
   background-position: center bottom 이라야 맞닿는 쪽이 앨범 아랫부분이 되고,
   마스크는 반전 '전' 좌표 기준이라 to top 이어야 맞닿는 쪽이 진해진다. */
.cf-reflect {
  position: absolute; top: 100%; left: 0;
  width: 100%; height: 50%;
  margin-top: 3px; border-radius: 4px;
  background-size: cover; background-position: center bottom; background-repeat: no-repeat;
  transform: scaleY(-1); transform-origin: center;
  opacity: .36; filter: blur(1px); pointer-events: none;
  transition: opacity 420ms ease;
  -webkit-mask-image: linear-gradient(to top, rgba(0,0,0,.95) 0%, rgba(0,0,0,.3) 42%, transparent 84%);
          mask-image: linear-gradient(to top, rgba(0,0,0,.95) 0%, rgba(0,0,0,.3) 42%, transparent 84%);
}
.cf-item.cf-flipped .cf-reflect,
.cf-item.cf-flipped .cf-shadow,
.cf-item.cf-flipped .cf-glow { opacity: 0; }

#cf-app.cf-flipmode #cf-stage { padding-bottom: 0; }

/* 세로가 짧은 화면(가로로 눕힌 폰)에서는 반사를 그릴 자리가 없다 */
#cf-app.cf-noreflect .cf-reflect { display: none; }

/* ── 재생 중 표시 ────────────────────────────────────────────────────────
   막대 3개짜리 이퀄라이저. 일시정지하면 멈추고 낮게 눕는다.               */
.cf-eq { display: inline-flex; align-items: flex-end; gap: .13em; height: .85em; }
.cf-eq i {
  display: block; width: .17em; height: 100%; border-radius: .08em;
  background: currentColor; transform-origin: 50% 100%;
  animation: cf-eq 900ms ease-in-out infinite;
}
.cf-eq i:nth-child(2) { animation-delay: -300ms; }
.cf-eq i:nth-child(3) { animation-delay: -600ms; }
.cf-paused .cf-eq i { animation-play-state: paused; transform: scaleY(.4); }
@keyframes cf-eq { 0%, 100% { transform: scaleY(.32); } 50% { transform: scaleY(1); } }

/* 커버 위의 재생 중 배지 — 앨범아트가 주인공이므로 최소한으로만 */
.cf-nowbadge {
  position: absolute; right: 6px; bottom: 6px; z-index: 2;
  display: none; align-items: center;
  padding: 3px 4px; border-radius: 3px;
  background: rgba(0,0,0,.4); color: rgba(255,255,255,.88);
  font-size: 10px; pointer-events: none;
}
.cf-item.cf-now .cf-nowbadge { display: inline-flex; }

/* ── 뒷면: 수록곡 ────────────────────────────────────────────────────────
   부모가 --cf-flip 배율만큼 확대되므로 안쪽 글자는 그 배율로 나눠 둔다.
   그래야 화면에 보이는 크기가 일정하다. 내부는 전부 em 으로 쓴다.        */
.cf-back {
  position: absolute; transform: rotateY(180deg);
  background: linear-gradient(160deg, #1f1f1f 0%, #121212 100%);
  display: flex; flex-direction: column;
  font-size: calc(15px / var(--cf-flip));
  border: 1px solid rgba(255,255,255,.08);
}
.cf-back::before {                      /* 곡이 적어 아래가 비면 허전하다 */
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-image: var(--cf-art, none); background-size: cover; background-position: center;
  filter: blur(26px) saturate(1.3); opacity: .16; pointer-events: none;
}
.cf-back > * { position: relative; z-index: 1; }

.cf-back-head {
  padding: 1em 1.1em .7em; flex: 0 0 auto;
  border-bottom: 1px solid rgba(255,255,255,.08);
  display: flex; gap: .8em; align-items: center;
}
.cf-back-thumb {
  width: 3.2em; height: 3.2em; border-radius: .25em; flex: 0 0 auto;
  background: #2a2a2a center/cover no-repeat; box-shadow: 0 .2em .6em rgba(0,0,0,.5);
}
.cf-back-titles { min-width: 0; }
.cf-back-title {
  font-size: 1.1em; font-weight: 700; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cf-back-sub {
  font-size: .85em; color: #a0a0a0; margin-top: .25em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.cf-tracks {
  flex: 1 1 auto; overflow-y: auto; overflow-x: hidden;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  padding: .3em 0; touch-action: pan-y;
}
.cf-tracks::-webkit-scrollbar { width: .5em; }
.cf-tracks::-webkit-scrollbar-thumb { background: rgba(255,255,255,.2); border-radius: 1em; }

/* 터치로 누를 수 있어야 하므로 줄 높이를 확장판보다 키웠다.
   글꼴이 15px 로 보이도록 맞춰져 있으므로 3.1em ≈ 화면상 46px — 44px 기준을 넘는다. */
.cf-row {
  display: flex; align-items: center; gap: .8em;
  padding: .45em 1.1em; min-height: 3.1em; cursor: pointer;
  transition: background .12s;
}
.cf-row:hover { background: rgba(255,255,255,.08); }
.cf-row.cf-sel { background: rgba(255,255,255,.14); }
.cf-row.cf-playing .cf-row-name { color: #1ed760; font-weight: 600; }
.cf-row.cf-off { opacity: .38; cursor: default; }
.cf-row-no {
  flex: 0 0 1.8em; text-align: right; color: #8a8a8a; font-size: .88em;
  font-variant-numeric: tabular-nums;
}
.cf-row-no .cf-eq { display: none; color: #1ed760; }
.cf-row.cf-playing .cf-row-no b { display: none; }
.cf-row.cf-playing .cf-row-no .cf-eq { display: inline-flex; }
/* span 은 인라인이라 display:block 없이는 text-overflow 가 듣지 않는다.
   긴 제목이 재생시간을 덮고 가로 스크롤이 생긴다. */
.cf-row-body { flex: 1 1 auto; min-width: 0; }
.cf-row-name {
  display: block; font-size: .95em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cf-row-art {
  display: block; font-size: .8em; color: #8a8a8a; margin-top: .1em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cf-row-dur {
  flex: 0 0 auto; color: #8a8a8a; font-size: .85em; font-variant-numeric: tabular-nums;
}

.cf-back-foot {
  flex: 0 0 auto; padding: .6em 1.1em .9em; display: flex; gap: .5em;
  border-top: 1px solid rgba(255,255,255,.08);
}
.cf-back-foot button {
  border: 0; border-radius: 500px; cursor: pointer; font-family: inherit;
  font-size: .88em; font-weight: 600; padding: .7em 1.1em;
  transition: background .15s, color .15s;
}
.cf-fb-play { background: #1db954; color: #000; }
.cf-fb-alt { background: rgba(255,255,255,.1); color: #ddd; }
.cf-loading {
  padding: 2em 1.4em; text-align: center; color: #7a7a7a; font-size: .9em;
  white-space: pre-line; line-height: 1.5;
}

/* ── 하단 정보 · 버튼 ────────────────────────────────────────────────────*/
#cf-meta {
  position: relative; z-index: 3; text-align: center;
  padding: 4px 20px 0; min-height: 60px;
  transition: opacity .3s ease;
}
#cf-title {
  font-size: 22px; font-weight: 700; letter-spacing: -.01em;
  text-shadow: 0 2px 14px rgba(0,0,0,.8);
  max-width: 86vw; margin: 0 auto;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#cf-artist { font-size: 14px; color: #b3b3b3; margin-top: 3px;
             overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#cf-year { font-size: 12px; color: #6f6f6f; margin-top: 2px; }

#cf-actions {
  position: relative; z-index: 3;
  display: flex; justify-content: center; gap: 8px;
  padding: 10px 12px 6px;
  transition: opacity .3s ease;
}
.cf-btn {
  border: 0; border-radius: 500px; cursor: pointer;
  font-size: 14px; font-weight: 600; padding: 12px 20px;
  transition: transform .1s, background .15s, color .15s;
}
.cf-btn:active { transform: scale(.96); }
.cf-btn.cf-primary { background: #1db954; color: #000; }
.cf-btn.cf-ghost { background: rgba(255,255,255,.1); color: #ddd; }

/* 뒤집으면 제목·버튼을 숨기는 데 그치지 않고 자리까지 비워 준다.
   가로로 눕힌 폰처럼 세로 여유가 없는 화면에서는, 이 자리를 돌려받아야
   뒷면 곡 목록이 읽을 만한 크기로 커진다. */
#cf-app.cf-flipmode #cf-meta,
#cf-app.cf-flipmode #cf-actions {
  opacity: 0; pointer-events: none;
  height: 0; min-height: 0; padding-top: 0; padding-bottom: 0; overflow: hidden;
}

/* ── 지금 재생 중 바 (화면 맨 아래) ──────────────────────────────────────*/
#cf-nowbar {
  position: relative; z-index: 6;
  display: none; align-items: center; gap: 10px;
  margin: 0 12px calc(env(safe-area-inset-bottom, 0px) + 10px);
  padding: 10px 14px; border-radius: 14px;
  background: rgba(255,255,255,.08); border: 0; color: #ddd;
  cursor: pointer; text-align: left; width: calc(100% - 24px);
}
#cf-nowbar.cf-on { display: flex; }
#cf-nowbar .cf-nowbar-text {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px;
}
#cf-nowbar .cf-nowbar-dev { flex: 0 0 auto; font-size: 11px; color: #8a8a8a; }

#cf-empty {
  position: absolute; inset: 0; z-index: 3; display: none;
  align-items: center; justify-content: center; color: #7a7a7a; font-size: 14px;
}
#cf-empty.cf-on { display: flex; }

/* ── 로그인 · 오류 화면 ──────────────────────────────────────────────────*/
#cf-gate {
  position: fixed; inset: 0; z-index: 20;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; padding: 32px; text-align: center; background: #000;
}
#cf-gate.cf-off { display: none; }
#cf-gate h1 { font-size: 22px; font-weight: 700; margin: 0; }
#cf-gate p { margin: 0; color: #9a9a9a; font-size: 14px; line-height: 1.6; max-width: 34em; }
#cf-gate pre {
  margin: 0; padding: 12px 14px; border-radius: 10px; max-width: 100%;
  background: rgba(255,255,255,.06); color: #d8d8d8;
  font-size: 12px; text-align: left; white-space: pre-wrap; word-break: break-all;
  user-select: text; -webkit-user-select: text;
}
#cf-gate .cf-btn { padding: 14px 28px; font-size: 15px; }

/* ── 기기 선택 시트 ──────────────────────────────────────────────────────*/
#cf-sheet {
  position: fixed; inset: 0; z-index: 30;
  display: none; align-items: flex-end; justify-content: center;
  background: rgba(0,0,0,.6);
}
#cf-sheet.cf-on { display: flex; }
.cf-sheet-box {
  width: 100%; max-width: 520px;
  background: #181818; border-radius: 16px 16px 0 0;
  padding: 18px 16px calc(env(safe-area-inset-bottom, 0px) + 18px);
  max-height: 76dvh; overflow-y: auto;
}
.cf-sheet-box h2 { margin: 0 0 4px; font-size: 16px; }
.cf-sheet-box .cf-hint { margin: 0 0 14px; font-size: 12px; color: #8a8a8a; line-height: 1.5; }
.cf-dev {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 14px 12px; margin-bottom: 8px;
  background: rgba(255,255,255,.07); border: 0; border-radius: 10px;
  color: #eee; font-size: 15px; text-align: left; cursor: pointer;
}
.cf-dev.cf-cur { background: rgba(30,215,96,.16); color: #1ed760; }
.cf-dev small { display: block; color: #8a8a8a; font-size: 11px; margin-top: 2px; }

/* ── 화면이 넓으면 커버를 더 크게, 좁으면 글자를 줄인다 ──────────────────*/
@media (max-width: 480px) {
  #cf-title { font-size: 19px; }
  #cf-count { display: none; }          /* 좁은 화면에서는 상단바를 비운다 */
  .cf-btn { padding: 11px 16px; font-size: 13px; }
}

/* 가로로 눕힌 폰 — 세로가 극단적으로 짧다. 위아래 군더더기를 걷어낸다. */
@media (max-height: 500px) {
  #cf-top { padding-top: calc(env(safe-area-inset-top, 0px) + 6px); padding-bottom: 6px; }
  #cf-search, .cf-chip { padding-top: 7px; padding-bottom: 7px; }
  #cf-meta { min-height: 44px; }
  #cf-title { font-size: 17px; }
  #cf-artist, #cf-year { font-size: 12px; }
  #cf-actions { padding: 6px 12px 4px; }
  .cf-btn { padding: 9px 14px; font-size: 13px; }
  #cf-nowbar { margin-bottom: calc(env(safe-area-inset-bottom, 0px) + 6px); padding: 8px 12px; }
  /* 뒤집었을 때는 재생 바까지 접어 화면을 곡 목록에 몰아준다 */
  #cf-app.cf-flipmode #cf-nowbar { display: none; }
}
