/* ── CSS Variables / Theme ── */
:root {
  /* Palette aligned with the companion site's home page.
     色卡与 reference/home-index.html 同根:
     深玫瑰灰 #6b4a55 / 柔雾粉棕 #85616f / 玫瑰 #c2708a / 深玫瑰 #984e68 / 奶油黄 #ffedc2,
     半透明奶白玻璃 + 1px 白边 + 柔粉阴影。Music 的主题落在「温柔唱片/音波」:
     奶油纸面上漂浮唱针玫瑰,封面缺失时是奶油底玫瑰音符小方块。 */
  --ink: #6b4a55;
  --ink-soft: #85616f;
  --muted: #ab8b98;
  --faint: #cfb6c0;
  --rose: #c2708a;
  --rose-deep: #984e68;
  --butter: #ffedc2;
  --accent: #984e68;                        /* 文字强调:深玫瑰,浅底上对比够(文字继续用它,别拿去刷按钮) */
  --accent-soft: #c2708a;                   /* 次级强调:玫瑰 */
  --btn: #D26E88;                           /* unified solid-button color (the only solid-button color site-wide) */
  --accent-tint: rgba(194, 112, 138, 0.14);
  --good: #4d9b7b;
  --bad: #d96a5e;
  --bg: #fdf4f2;                            /* 平坦底色,供 color-mix 使用 */
  --milk: rgba(255, 255, 255, 0.62);        /* 奶白玻璃卡 */
  --milk-strong: rgba(255, 255, 255, 0.82);
  --line: rgba(255, 255, 255, 0.9);         /* 玻璃卡 1px 白边 */
  --hairline: rgba(194, 112, 138, 0.16);    /* 卡片之间的发丝线 */
  --font-ui: -apple-system, BlinkMacSystemFont, "SF Pro Rounded", "PingFang SC", "Microsoft YaHei", sans-serif;
  --font-mono: "SF Mono", "Fira Code", "Cascadia Code", monospace;
  --font-script: "Snell Roundhand", "Savoye LET", "Brush Script MT", cursive;
  --shadow-soft: 0 12px 32px rgba(214, 120, 170, 0.16);
  --shadow-sm: 0 4px 14px rgba(150, 90, 110, 0.10);
  --r-s: 12px; --r-m: 20px; --r-full: 999px;
  --blur: blur(18px) saturate(1.14);
  --safe-bottom: env(safe-area-inset-bottom, 0px);

  /* ── Motion system (damso-inspired easing) ──
     扒 damso.com 扒出来的配方：全站 19 处 expo.inOut、16 处 duration:1、Lenis lerp .12。
     我们原来是清一色 0.18s + 浏览器默认 ease —— 每个动作「啪」一下就完事，
     没有过程感，这才是「像小学生」的技术根因（不是粉色的错）。

     铁律：只动 transform 和 opacity。这两个走合成器，不触发布局。
     歌词行原本 transition 里带 font-size，每帧重排整列，移动端必卡 —— 已改 scale。

        Interaction first, timing tuned at the end.
     所以时长全部收在这四个变量里，调一处全站跟着走。 */
  --ease-out:    cubic-bezier(.16, 1, .3, 1);      /* ≈ expo.out：猛起步、极缓收尾，主力 */
  --ease-in-out: cubic-bezier(.87, 0, .13, 1);     /* ≈ expo.inOut：转场用，两头都稳 */
  --ease-spring: cubic-bezier(.22, 1.12, .44, 1);  /* 轻微过冲，按压回弹用 */
  --ease-press:  cubic-bezier(.4, 0, .2, 1);       /* 按下去要跟手，这条不能慢 */

  --t-press: .12s;   /* 按下：必须即时 */
  --t-fast:  .3s;    /* 小元件：药丸、图标、勾选 */
  --t-base:  .55s;   /* 主力：入场、卡片、封面 */
  --t-slow:  .9s;    /* 大转场：页面切换、唱片起转 */
  --stagger: 42ms;   /* 列表逐行错开的间隔 */
}

@media (prefers-reduced-motion: reduce) {
  :root { --t-press: 0s; --t-fast: 0s; --t-base: 0s; --t-slow: 0s; --stagger: 0ms; }
}

/* ── Reset ── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
  height: 100%; width: 100%;
  height: 100dvh;
  font-family: var(--font-ui);
  color: var(--ink);
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
  /* Background: watercolor paper (several earlier attempts retired).
     ——最终按参考图一号来:一块干净的素粉,什么都不贴什么都不叠。
     玻璃卡的层次交给卡自己的白边和粉影,不靠背景花活。 */
  background: #fbeff4;
}
button { font-family: inherit; cursor: pointer; }
input { font-family: inherit; }
img { display: block; }
button:focus-visible, input:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid rgba(152, 78, 104, 0.55);
  outline-offset: 2px;
  border-radius: 8px;
}

/* ── App Shell ── */
#app {
  width: 100%; height: 100%; height: 100dvh;
  display: flex; flex-direction: column;
  overflow: hidden; position: relative;
}
/* 桌面独立窗别无限拉开:内容收窄成舞台,两侧留给家的背景。 */
@media (min-width: 560px) {
  #app {
    max-width: 460px; margin: 0 auto;
    border-inline: 1px solid rgba(255, 255, 255, 0.75);
    box-shadow: 0 0 60px rgba(214, 120, 170, 0.14);
  }
  .lyrics-view, .memory-view { max-width: 460px; margin-inline: auto; }
}
#app > *:not(.lyrics-view):not(.memory-view):not(.mv-view) { position: relative; z-index: 1; }

/* ── Top Bar ── */
.topbar {
  min-height: 52px; padding: 4px 12px 4px 12px;
  display: flex; align-items: center; gap: 6px; flex-shrink: 0;
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  background: rgba(255, 250, 252, 0.55);
  border-bottom: 1px solid var(--hairline);
  padding-top: env(safe-area-inset-top, 0px);
}
.topbar-title {
  flex: 1; font-family: var(--font-script);
  font-size: 24px; font-weight: 500; color: var(--rose-deep);
  text-align: center; letter-spacing: 0.5px; line-height: 1.2;
}
.topbar-btn {
  width: 36px; height: 36px; flex-shrink: 0;
  background: var(--milk); border: 1px solid var(--line); border-radius: var(--r-full);
  color: var(--rose-deep); text-decoration: none;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-base) var(--ease-spring), box-shadow var(--t-base) var(--ease-out);
}
.topbar-btn:active { transform: scale(0.9); }

/* ── Body (tab content) ── */
.tab-body {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}
.tab-body::-webkit-scrollbar, .ly-lines::-webkit-scrollbar, .sm-body::-webkit-scrollbar { width: 6px; }
.tab-body::-webkit-scrollbar-thumb,
.ly-lines::-webkit-scrollbar-thumb,
.sm-body::-webkit-scrollbar-thumb {
  background: rgba(194, 112, 138, 0.35); border-radius: 999px;
}

/* ── Bottom Nav ──
   主页 dock 的姊妹件:奶油玻璃长条,圆角收紧,选中项深玫瑰。 */
.bottom-nav {
  display: flex; justify-content: space-around; align-items: center;
  margin: 6px 10px calc(var(--safe-bottom) + 10px);
  padding: 6px 8px;
  border: 1px solid var(--line); border-radius: var(--r-full);
  background: rgba(255, 250, 252, 0.72);
  backdrop-filter: blur(22px) saturate(1.15); -webkit-backdrop-filter: blur(22px) saturate(1.15);
  box-shadow: 0 14px 34px rgba(194, 112, 138, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.9);
  flex-shrink: 0;
}
.nav-item {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: none; border: none; color: var(--muted);
  font-size: 10px; letter-spacing: 0.4px; padding: 7px 18px;
  border-radius: var(--r-full);
  transition: color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out), transform var(--t-base) var(--ease-spring);
}
.nav-item:active { transform: translateY(1px); }
.nav-item.active { color: var(--rose-deep); background: rgba(194, 112, 138, 0.12); }
.nav-item.active span { font-weight: 600; }
.nav-item svg {
  fill: none; stroke: currentColor; stroke-width: 1.5;
  transition: stroke-width var(--t-fast) var(--ease-out);
}
/* 原本选中态是 fill: currentColor —— 房子图标填实还认得出，
   但音符和放大镜一填就是一坨黑块（8-10 实拍抓到）。
   改成加粗描边：图标始终是同一个图标，只是「重」了一点。 */
.nav-item.active svg { fill: none; stroke-width: 2.1; }

/* ── 通用奶白玻璃卡 / 空状态 ── */
.card {
  background: var(--milk); border: 1px solid var(--line); border-radius: var(--r-m);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow-soft);
}
/* .empty-card（虚线框 + 大 emoji + 两行教学文案）8-10 已整体退役，
   改用样式表末尾的 .empty-line：一行轻声的字，说完就让位。 */

/* ── 封面:缺失时的奶油音符占位 ── */
.coverbx {
  position: relative; overflow: hidden; flex-shrink: 0;
  display: grid; place-items: center;
  background: linear-gradient(150deg, rgba(194, 112, 138, 0.2), rgba(255, 237, 194, 0.62));
  color: rgba(152, 78, 104, 0.6);
}
.coverbx::before {
  content: "♪"; font-size: 1em; line-height: 1;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
}
.coverbx::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.22), transparent 45%);
}
.coverbx img {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
}
.coverbx img.gone { display: none; }

/* ── Now Playing (mini) Bar ── */
.np-bar {
  height: 58px; flex-shrink: 0; margin: 6px 12px 2px;
  background: var(--milk-strong);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  border: 1px solid var(--line); border-radius: 18px;
  box-shadow: var(--shadow-sm);
  display: flex; align-items: center; gap: 10px; padding: 0 8px 0 7px;
  cursor: pointer; position: relative; overflow: hidden;
}
.np-bar.hidden { display: none; }
.np-cover { width: 44px; height: 44px; border-radius: 12px; font-size: 16px; }
.np-info { flex: 1; min-width: 0; overflow: hidden; }
.np-name { font-size: 13px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-artist { font-size: 11px; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.np-btn {
  width: 38px; height: 38px; border-radius: var(--r-full); flex-shrink: 0;
  background: var(--btn); border: none; color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 12px rgba(152, 78, 104, 0.35);
  transition: transform var(--t-base) var(--ease-spring);
}
.np-btn:active { transform: scale(0.9); }
.np-next-btn {
  background: none; border: none; color: var(--accent-soft); padding: 8px; flex-shrink: 0;
  border-radius: var(--r-full);
}
.np-next-btn:active { transform: scale(0.9); }
.np-progress {
  position: absolute; top: 0; left: 0; height: 2px; border-radius: 999px;
  background: var(--btn);
  transition: width 0.3s linear;
}

/* The player lives in its own named window. Mini mode turns that window itself
   into the global floating player; no page or iframe is nested inside another.
   迷你窗目标尺寸 360×150:整窗就是一块玫瑰奶糖。 */
body.window-mini .topbar,
body.window-mini .tab-body,
body.window-mini .bottom-nav,
body.window-mini .lyrics-view,
body.window-mini .memory-view { display: none !important; }
body.window-mini #app { min-height: 112px; }
body.window-mini .np-bar {
  display: flex !important;
  flex: 1 1 auto; height: 100dvh; min-height: 112px;
  gap: 14px; padding: 14px 16px; margin: 0;
  border: 0; border-radius: 0; overflow: hidden;
  background:
    radial-gradient(circle at 85% 20%, rgba(255, 237, 194, 0.6), transparent 46%),
    linear-gradient(135deg, rgba(194, 112, 138, 0.2), rgba(255, 251, 246, 0.9) 70%);
}
body.window-mini .np-cover {
  width: 66px; height: 66px; border-radius: var(--r-full);
  font-size: 22px;
  box-shadow: 0 6px 18px rgba(150, 90, 110, 0.25), inset 0 0 0 2px rgba(255, 255, 255, 0.8);
}
/* 迷你窗里封面做成小唱片:中心一枚奶油唱孔 */
body.window-mini .np-cover::after {
  content: ""; position: absolute; inset: 0; z-index: 2;
  border-radius: 50%;
  background:
    radial-gradient(circle, rgba(255, 251, 246, 0.95) 0 3px, rgba(214, 120, 170, 0.25) 3px 6px, transparent 6px),
    repeating-radial-gradient(circle, transparent 0 9px, rgba(255, 255, 255, 0.16) 9px 10px);
}
body.window-mini .np-name { font-size: 14px; }
body.window-mini .np-artist { margin-top: 3px; font-size: 11px; }
body.window-mini .np-btn { width: 44px; height: 44px; }
body.window-mini .np-btn svg { width: 24px; height: 24px; }
body.window-mini .np-progress { top: auto; bottom: 0; height: 3px; }

/* ── 抽屉形态（聊天页「一起听」的 iframe）──
   顶栏在 JS 里就没渲染，这里管的是「剩下的东西怎么在 561px 里活得好」。
   原则同上：不是等比缩小，是砍掉「逛」的功能、把高度还给「听」。 */
body.embedded #app { max-width: none; border-inline: 0; box-shadow: none; }

/* 导航从「图标上、文字下」的两行大方块，改成一行横排小药丸：62px → 44px。 */
body.embedded .bottom-nav {
  margin: 4px 10px calc(var(--safe-bottom) + 6px);
  padding: 4px 6px;
}
body.embedded .nav-item {
  flex-direction: row; gap: 6px; padding: 7px 14px; font-size: 11.5px;
}
body.embedded .nav-item svg { width: 16px; height: 16px; }
body.embedded .np-bar { height: 52px; margin: 4px 10px 0; }
body.embedded .np-cover { width: 40px; height: 40px; }
/* 抽屉矮，歌词页的留白按比例收，不然一屏只剩两三行歌词 */
body.embedded .ly-lines { padding: clamp(28px, 12dvh, 80px) 22px clamp(36px, 15dvh, 96px); }
body.embedded .ly-cover-area { padding: 2px 18px 12px; }
body.embedded .ly-controls { padding: 6px 20px calc(var(--safe-bottom) + 10px); }

/* ── 入场编排（damso 的 stagger）──
   原来列表是整块「啪」地出现。现在逐行错开 --stagger，最多排到第 14 行，
   再往后一起进 —— 不然长歌单最后一行要等两秒才露面。
   只动 transform / opacity，不碰布局。 */
@keyframes stagger-in {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: none; }
}
.stagger-in {
  animation: stagger-in var(--t-base) var(--ease-out) backwards;
  animation-delay: calc(min(var(--i, 0), 14) * var(--stagger));
}

/* ── Tab 药丸滑动跟随 ──
   原来选中态是直接换 background，硬切。现在药丸本体是一个独立元素，
   在 nav 里滑过去；JS 只负责量位置写 --x/--w，动画交给 CSS。 */
.bottom-nav { position: relative; }
.nav-ink {
  position: absolute; left: 0; top: 50%; z-index: 0;
  height: calc(100% - 12px); width: var(--w, 0px);
  transform: translate3d(var(--x, 0px), -50%, 0);
  background: rgba(194, 112, 138, 0.12);
  border-radius: var(--r-full);
  transition: transform var(--t-base) var(--ease-out),
              width var(--t-base) var(--ease-out);
  pointer-events: none;
}
.nav-ink.silent { transition: none; }   /* 首帧定位别从左上角滑过来 */
.nav-item { position: relative; z-index: 1; }
/* 药丸已经由 .nav-ink 画了，选中项自己就别再铺一层背景 */
.nav-item.active { background: none; }

/* Tab 切换：整页轻轻淡入，行内的错落交给 .stagger-in，两层叠出层次。 */
@keyframes tab-enter { from { opacity: 0; } to { opacity: 1; } }
.tab-body.tab-enter { animation: tab-enter var(--t-fast) var(--ease-out); }

/* ── 拆卡片：空状态从「虚线框 + 大图标 + 两行说明」改成一行轻声细语 ──
   那个虚线框是「小学生感」最重的一处：一整屏就为了说「还没听过歌」，
   还要配个大音符和一句教学文案。damso 的空位就是空着。 */
.empty-line {
  padding: 18px 0; color: var(--muted); font-size: 12.5px;
  letter-spacing: .02em;
}
/* 歌单/搜索结果里的空状态不在 .section 里，得自己补上左右边距 */
.pls-list > .empty-line, .song-list > .empty-line { padding-inline: 16px; }

/* ── Home Tab ── */
.home-tab { padding: 10px 0 18px; }
.home-card {
  margin: 4px 14px 4px;
  background: var(--milk); border: 1px solid var(--line); border-radius: 22px;
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}
.home-hero {
  position: relative; height: 150px;
  background:
    radial-gradient(circle at 82% 30%, rgba(255, 237, 194, 0.7), transparent 52%),
    repeating-radial-gradient(circle at 118% -10%, rgba(194, 112, 138, 0.22) 0 2px, transparent 2px 26px),
    linear-gradient(130deg, rgba(194, 112, 138, 0.3), rgba(255, 219, 208, 0.4) 55%, rgba(255, 237, 194, 0.45));
}
.home-profile {
  position: relative; display: flex; flex-direction: column; align-items: center;
  padding: 0 20px 22px;
}
.home-avatar {
  width: 78px; height: 78px; border-radius: 50%; overflow: hidden; cursor: pointer;
  border: 3px solid rgba(255, 255, 255, 0.95);
  background: linear-gradient(150deg, rgba(194, 112, 138, 0.2), rgba(255, 237, 194, 0.65));
  display: flex; align-items: center; justify-content: center;
  margin-top: -39px; position: relative; z-index: 1;
  box-shadow: 0 8px 22px rgba(214, 120, 170, 0.28);
}
.home-avatar span { font-size: 26px; color: var(--rose-deep); opacity: 0.7; font-weight: 300; }
.home-avatar img { width: 100%; height: 100%; object-fit: cover; }
.home-name {
  margin-top: 9px; font-size: 17px; font-weight: 700; color: var(--ink);
  letter-spacing: 0.6px; cursor: pointer;
  padding: 2px 10px; border-radius: var(--r-full);
  transition: background var(--t-fast) var(--ease-out);
}
@media (hover: hover) { .home-name:hover { background: rgba(194, 112, 138, 0.1); } }
.home-sig {
  margin-top: 4px; font-size: 12.5px; color: var(--ink-soft);
  cursor: pointer; text-align: center; max-width: 80%; line-height: 1.6;
  border-bottom: 1px dashed rgba(194, 112, 138, 0.4);
  padding-bottom: 2px;
}
.home-edit-wrap { display: flex; gap: 6px; margin-top: 8px; width: 80%; align-items: center; }
.home-edit-input {
  flex: 1; min-width: 0; border: 1px solid var(--hairline); border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.75);
  font-size: 13px; color: var(--ink); outline: none; text-align: center; padding: 8px 14px;
}
.home-edit-input:focus { border-color: var(--accent-soft); }
.home-edit-ok {
  background: var(--btn); border: none; color: #fff; border-radius: var(--r-full);
  padding: 8px 16px; font-size: 12px; flex-shrink: 0;
  box-shadow: 0 4px 12px rgba(152, 78, 104, 0.3);
}

/* ── Section ── */
.section { padding: 16px 16px 0; }
/* 0.18em 的字距是给全大写英文用的；中文标题被它撑成「最近 在听」，
   一眼就散（8-10 实拍抓到）。中文收到近乎 0，英文标题另开一档。 */
.section-hd {
  font-size: 11.5px; font-weight: 600; color: var(--accent);
  margin-bottom: 10px; letter-spacing: 0.02em;
  display: flex; align-items: center; gap: 8px;
}
.section-hd.en { letter-spacing: 0.18em; }
/* 那条横线撤了 —— 拆卡片同理：分区靠间距分，不靠画线分。 */

/* ── Recent List ── */
.recent-list { display: flex; flex-direction: column; gap: 6px; }
.recent-row {
  display: flex; align-items: center; gap: 12px; padding: 8px 10px;
  cursor: pointer; border-radius: 14px;
  background: rgba(255, 255, 255, 0.55); border: 1px solid rgba(255, 255, 255, 0.8);
  transition: transform var(--t-base) var(--ease-spring), background var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out);
}
@media (hover: hover) {
  .recent-row:hover { background: rgba(255, 255, 255, 0.82); border-color: var(--line); }
}
.recent-row:active { transform: scale(0.985); background: var(--milk-strong); }
.recent-row-cover { width: 46px; height: 46px; border-radius: 11px; font-size: 16px; }
.recent-row-info { flex: 1; min-width: 0; }
.recent-row-name { font-size: 13.5px; font-weight: 600; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.recent-row-artist { font-size: 11.5px; color: var(--ink-soft); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }

/* ── Playlists Tab ── */
.pls-tab { padding: 12px 16px 18px; }
.pls-hd { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.pls-title { font-size: 11.5px; font-weight: 600; color: var(--accent); letter-spacing: 0.18em; }
.pls-add {
  width: 34px; height: 34px; border-radius: var(--r-full); border: 1px solid var(--line);
  background: var(--milk); color: var(--accent); font-size: 19px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-base) var(--ease-spring);
}
.pls-add:active { transform: scale(0.9); }
.pls-create { display: flex; gap: 8px; margin-bottom: 12px; align-items: center; }
.pls-create-input {
  flex: 1; min-width: 0; border: 1px solid var(--hairline); border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.75);
  font-size: 13px; color: var(--ink); outline: none; padding: 9px 16px;
}
.pls-create-input:focus { border-color: var(--accent-soft); }
.pls-create-ok {
  background: var(--btn); border: none; color: #fff; border-radius: var(--r-full);
  padding: 9px 16px; font-size: 12px; flex-shrink: 0;
}
.pls-create-cancel {
  background: none; border: none; color: var(--muted); padding: 8px; border-radius: var(--r-full);
}
.pls-list { display: flex; flex-direction: column; gap: 8px; }
.pls-row {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px;
  cursor: pointer; border-radius: 16px;
  background: var(--milk); border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-base) var(--ease-spring), background var(--t-fast) var(--ease-out);
}
@media (hover: hover) { .pls-row:hover { background: var(--milk-strong); } }
.pls-row:active { transform: scale(0.98); }
.pls-row-cover {
  width: 52px; height: 52px; border-radius: 13px; flex-shrink: 0;
  background: linear-gradient(150deg, rgba(194, 112, 138, 0.2), rgba(255, 237, 194, 0.6));
  background-size: cover; background-position: center;
  display: flex; align-items: center; justify-content: center;
  color: rgba(152, 78, 104, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.8);
}
.pls-row-info { flex: 1; min-width: 0; }
.pls-row-name {
  font-size: 14.5px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pls-row-count { font-size: 11.5px; color: var(--ink-soft); margin-top: 3px; }
.pls-row-del {
  background: none; border: none; color: var(--faint); flex-shrink: 0; padding: 10px;
  border-radius: var(--r-full); transition: color var(--t-fast) var(--ease-out);
}
.pls-row-del:active { color: var(--bad); transform: scale(0.92); }

/* ── Playlist Detail ── */
.pl-detail { padding: 8px 16px 18px; }
.pl-detail-hd { display: flex; align-items: center; gap: 8px; padding: 6px 0; }
.pl-detail-title { font-size: 17px; font-weight: 700; color: var(--ink); flex: 1; min-width: 0; }
.pl-detail-meta { font-size: 11.5px; color: var(--ink-soft); margin-bottom: 12px; letter-spacing: 0.06em; }
.pl-rename { display: flex; gap: 6px; flex: 1; align-items: center; }
.pl-rename-input {
  flex: 1; min-width: 0; border: 1px solid var(--hairline); border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.75);
  font-size: 14px; color: var(--ink); outline: none; padding: 8px 14px;
}
.pl-rename-ok {
  background: var(--btn); border: none; color: #fff; border-radius: var(--r-full);
  padding: 8px 14px; font-size: 12px; flex-shrink: 0;
}
.play-all {
  display: inline-flex; align-items: center; gap: 7px; padding: 9px 22px;
  border-radius: var(--r-full); background: var(--btn); color: #fff; border: none;
  font-size: 12.5px; font-weight: 600; margin-bottom: 12px;
  box-shadow: 0 6px 16px rgba(152, 78, 104, 0.32);
  transition: transform var(--t-base) var(--ease-spring);
}
.play-all:active { transform: scale(0.95); }
.back-btn {
  background: none; border: none; color: var(--rose-deep); padding: 8px;
  border-radius: var(--r-full); display: flex; align-items: center;
}

/* ── Song List ──
   小奶白大盘子,行与行之间只有发丝线;正在播的那一行是玫瑰糖水。 */
.song-list {
  display: flex; flex-direction: column;
  background: var(--milk); border: 1px solid var(--line); border-radius: var(--r-m);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}
.song-row {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  border-bottom: 1px solid rgba(194, 112, 138, 0.1);
  transition: background var(--t-fast) var(--ease-out);
}
.song-row:last-child { border-bottom: 0; }
@media (hover: hover) { .song-row:hover { background: rgba(255, 255, 255, 0.5); } }
.song-row.active {
  background: linear-gradient(90deg, rgba(194, 112, 138, 0.16), rgba(194, 112, 138, 0.05));
  box-shadow: inset 3px 0 0 var(--accent-soft);
}
.song-idx {
  width: 20px; font-size: 11px; color: var(--faint);
  text-align: center; flex-shrink: 0; font-family: var(--font-mono);
}
.song-row.active .song-idx { color: var(--accent); opacity: 1; font-weight: 700; }
.song-cover { width: 40px; height: 40px; border-radius: 10px; cursor: pointer; font-size: 15px; }
.song-info { flex: 1; min-width: 0; cursor: pointer; }
.song-name { font-size: 13.5px; font-weight: 500; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.song-row.active .song-name { color: var(--accent); font-weight: 700; }
.song-artist { font-size: 11px; color: var(--ink-soft); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.song-rm { background: none; border: none; color: var(--faint); flex-shrink: 0; padding: 10px 4px; }
.song-rm:active { color: var(--bad); transform: scale(0.92); }

/* ── Playlist detail hero card (glass style) ──
   一张大玻璃卡:封面 + PLAYLIST 眉题 + 歌单名 + 「♡ N songs」+ 圆形播放钮;
   列表顶上加一行列头(# TITLE ♡),唱片行目录页的做派。 */
.pl-hero {
  position: relative; display: flex; align-items: center; gap: 16px;
  padding: 18px; margin: 2px 0 14px;
  background: var(--milk); border: 1px solid var(--line); border-radius: var(--r-m);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow-soft);
}
.pl-hero-cover {
  width: 96px; height: 96px; border-radius: 16px; flex-shrink: 0; font-size: 34px;
  border: 1px solid var(--line); box-shadow: var(--shadow-sm);
}
.pl-hero-info { flex: 1; min-width: 0; }
.pl-hero-eyebrow {
  font-size: 10px; font-weight: 700; letter-spacing: 0.3em;
  color: var(--accent-soft); margin-bottom: 4px;
}
.pl-hero .pl-detail-title {
  font-size: 21px; font-weight: 800; line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pl-hero-meta { font-size: 11.5px; color: var(--ink-soft); margin-top: 5px; letter-spacing: 0.05em; }
.pl-play-fab {
  width: 46px; height: 46px; border-radius: var(--r-full); border: none; flex-shrink: 0;
  background: var(--btn); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 16px rgba(152, 78, 104, 0.32);
  transition: transform var(--t-base) var(--ease-spring);
  align-self: flex-end;
}
.pl-play-fab svg { margin-left: 2px; }
.pl-play-fab:active { transform: scale(0.92); }
.song-cols {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px 8px;
  border-bottom: 1px solid var(--hairline);
  font-size: 10px; font-weight: 700; letter-spacing: 0.22em; color: var(--faint);
}
.song-cols-idx { width: 20px; text-align: center; letter-spacing: 0; }
.song-cols-title { flex: 1; }
.song-cols-like { width: 34px; text-align: center; letter-spacing: 0; }
/* 抽屉里空间小,大头卡缩一号(按场景裁,不等比缩) */
body.embedded .pl-hero { gap: 12px; padding: 13px 14px; }
body.embedded .pl-hero-cover { width: 68px; height: 68px; border-radius: 12px; font-size: 24px; }
body.embedded .pl-hero .pl-detail-title { font-size: 17px; }
body.embedded .pl-play-fab { width: 40px; height: 40px; }
/* 底栏眉题:参考图那句手写体 Now playing… */
.np-eyebrow {
  font-family: var(--font-script); font-size: 11.5px; color: var(--accent-soft);
  line-height: 1; margin-bottom: 2px; white-space: nowrap;
}
body.window-mini .np-eyebrow { display: none; }
.like-btn {
  background: none; border: none; color: var(--faint);
  cursor: pointer; flex-shrink: 0; padding: 8px;
  border-radius: var(--r-full);
  transition: color var(--t-fast) var(--ease-out), transform var(--t-base) var(--ease-spring);
}
.like-btn.liked { color: var(--accent-soft); }
.like-btn:active { transform: scale(0.85); }
.queue-btn {
  background: none; border: none; color: var(--faint);
  cursor: pointer; flex-shrink: 0; padding: 8px;
  border-radius: var(--r-full);
  transition: color var(--t-fast) var(--ease-out), transform var(--t-base) var(--ease-spring);
}
.queue-btn:active { color: var(--accent); transform: scale(0.85); }
.search-clear.hidden { display: none; }

/* ── Discover Tab ── */
.discover-tab { padding-bottom: 18px; }
.discover-top { padding: 12px 16px 0; }
.discover-title {
  font-size: 11.5px; font-weight: 600; color: var(--accent); letter-spacing: 0.18em;
  margin-bottom: 10px;
  display: flex; align-items: center; gap: 8px;
}
.discover-title::after { content: ""; flex: 1; height: 1px; background: var(--hairline); }
.search-bar {
  display: flex; align-items: center; gap: 8px; padding: 5px 6px 5px 15px;
  background: var(--milk-strong); border: 1px solid var(--line);
  border-radius: var(--r-full); color: var(--ink-soft);
  box-shadow: var(--shadow-sm);
}
.search-bar:focus-within { border-color: var(--accent-soft); }
.search-input {
  flex: 1; border: none; background: transparent; font-size: 13.5px; color: var(--ink);
  outline: none; min-width: 0; padding: 6px 0;
}
.search-input::placeholder { color: var(--muted); }
.search-clear { background: none; border: none; color: var(--muted); padding: 8px; border-radius: var(--r-full); display: flex; }
.search-go {
  background: var(--btn); border: none; color: #fff; border-radius: var(--r-full);
  padding: 8px 18px; font-size: 12.5px; font-weight: 600; flex-shrink: 0;
  transition: transform var(--t-base) var(--ease-spring);
}
.search-go:active { transform: scale(0.94); }
.roam-pill {
  display: inline-flex; align-items: center; gap: 6px; margin: 10px 16px 0;
  padding: 7px 15px; border-radius: var(--r-full); font-size: 11.5px; cursor: pointer;
  background: rgba(255, 255, 255, 0.5); border: 1px solid var(--hairline);
  color: var(--ink-soft);
  transition: color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out),
              border-color var(--t-fast) var(--ease-out), transform var(--t-base) var(--ease-spring);
}
.roam-pill.active {
  color: #fff; background: var(--btn); border-color: transparent;
  box-shadow: 0 4px 12px rgba(152, 78, 104, 0.3);
}

/* ── Lyrics View (fullscreen) ──
   布局三件套别动:position:fixed / flex min-height:0 / 手动滚动。这里只换皮肤。 */
.lyrics-view {
  position: fixed; inset: 0; z-index: 100;
  width: 100%; height: 100%; height: 100dvh;
  min-height: 0; overflow: hidden; overscroll-behavior: none;
  display: flex; flex-direction: column;
  background: var(--bg);
  background-image: linear-gradient(
    color-mix(in srgb, var(--bg) 85%, transparent),
    color-mix(in srgb, var(--bg) 90%, transparent));
  transition: transform var(--t-slow) var(--ease-in-out);
}
.lyrics-view.hidden { transform: translateY(100%); pointer-events: none; }
/* 歌词页背景：底下一朵跟着歌转的李萨如（两个频率的比＝这首歌的一个音程），
   1px 线，很淡；字压在花上。画布垫在最底，其余子元素抬到 z-index:1。 */
.ly-liss { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; opacity: .35; }   /* 保持低对比度 */
.lyrics-view > *:not(.ly-liss) { position: relative; z-index: 1; }
.ly-header {
  padding: 12px 16px; display: flex; align-items: center; justify-content: space-between;
  padding-top: calc(env(safe-area-inset-top, 0px) + 12px);
  flex-shrink: 0;
}
.ly-close {
  background: var(--milk); border: 1px solid var(--line); color: var(--rose-deep);
  font-size: 18px; cursor: pointer; padding: 0;
  width: 36px; height: 36px; border-radius: var(--r-full);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-sm);
}
.ly-mem-btn {
  background: var(--milk); border: 1px solid var(--line); color: var(--rose-deep);
  cursor: pointer; padding: 0;
  width: 36px; height: 36px; border-radius: var(--r-full);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-base) var(--ease-spring);
}
.ly-mem-btn:active { transform: scale(0.9); }
/* 歌词页右上角工具排:从两颗长到五颗(♥✎💬🎬➕),8-31 收尾针二连:
      Compact sizing so all five buttons fit narrow screens. */
.ly-head-tools { display: flex; align-items: center; gap: 5px; flex-wrap: nowrap; min-width: 0; }
.ly-head-tools .ly-mem-btn { width: 32px; height: 32px; flex: 0 0 auto; }
.ly-head-tools .ly-mem-btn svg { width: 15px; height: 15px; }
.ly-like-btn.liked, .np-like-btn.liked { color: var(--accent); }
.np-like-btn {
  background: none; border: none; color: var(--accent-soft);
  padding: 8px; flex-shrink: 0; border-radius: var(--r-full);
  display: flex; align-items: center; justify-content: center;
  transition: color var(--t-fast) var(--ease-out), transform var(--t-base) var(--ease-spring);
}
.np-like-btn:active { transform: scale(0.85); }
.ly-cover-area { display: flex; align-items: center; gap: 14px; padding: 2px 20px 16px; flex-shrink: 0; }

/* ── Vinyl disc（本地改动：重新启用，嵌在玻璃卡里当封面） ──
   原来是 58px 圆角小方块，静止不动，看不出这是个「在放歌」的地方。
   现在是一张会转的唱片：封面裁成圆、中心一个孔、外圈一道压印。

   停转不能是急停。CSS 的 animation-play-state:paused 就是急停 ——
   真唱机断电后盘还会靠惯性再飘一段。所以暂停走 spinDown()：
   读下当前角度、脱离 animation、再用 ease-out 多转 22° 停下。
   起转同理，从当前角度接着转，不回弹到 0。 */
.ly-disc-wrap { flex-shrink: 0; padding: 3px; }
.ly-disc {
  position: relative; width: 74px; height: 74px; border-radius: 50%;
  box-shadow: 0 8px 22px rgba(150, 90, 110, 0.26),
              inset 0 0 0 1px rgba(255, 255, 255, 0.55);
  /* 唱片压纹：一圈极淡的同心线，转起来才看得出在动 */
  background:
    repeating-radial-gradient(circle at 50% 50%,
      rgba(107, 74, 85, 0.09) 0 1px, transparent 1px 4px),
    var(--rose-deep);
  will-change: transform;
}
.ly-disc .ly-cover {
  width: 100%; height: 100%; border-radius: 50%; font-size: 18px;
  /* 封面稍微内缩，露出一圈黑胶边 */
  transform: scale(.82); box-shadow: none;
}
.ly-disc-hole {
  position: absolute; left: 50%; top: 50%; width: 13px; height: 13px;
  transform: translate(-50%, -50%); border-radius: 50%;
  background: var(--bg);
  box-shadow: inset 0 0 0 1px rgba(107, 74, 85, 0.22),
              0 0 0 3px rgba(255, 255, 255, 0.5);
}
@keyframes disc-spin {
  from { transform: rotate(var(--spin-from, 0deg)); }
  to   { transform: rotate(calc(var(--spin-from, 0deg) + 360deg)); }
}
.ly-disc.spinning { animation: disc-spin 9s linear infinite; }
@media (prefers-reduced-motion: reduce) {
  .ly-disc.spinning { animation: none; }
}
/* ── Lyrics hero card + bottom deck (glass style) ── */
.ly-card {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 14px;
  padding: 14px 16px;
  background: var(--milk); border: 1px solid var(--line); border-radius: var(--r-m);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow-soft);
}
.ly-cover-sq {
  width: 72px; height: 72px; border-radius: 14px; flex-shrink: 0; font-size: 24px;
  border: 1px solid var(--line); box-shadow: var(--shadow-sm);
}
.ly-eyebrow {
  font-size: 10px; font-weight: 700; letter-spacing: 0.3em;
  color: var(--accent-soft); margin-bottom: 3px;
}
/* 二稿:一行胶囊(chat 输入条的语汇——奶白胶囊+玫瑰实心钮),高度砍一半 */
.ly-deck {
  flex-shrink: 0; margin: 0 14px calc(var(--safe-bottom) + 12px);
  display: flex; align-items: center; gap: 2px;
  background: var(--milk); border: 1px solid var(--line); border-radius: var(--r-full);
  backdrop-filter: var(--blur); -webkit-backdrop-filter: var(--blur);
  box-shadow: var(--shadow-soft);
  padding: 7px 14px 7px 8px;
}
.ly-deck .ly-play-btn { width: 34px; height: 34px; box-shadow: 0 4px 12px rgba(210, 110, 136, 0.35); }
.ly-deck .ly-skip-btn { padding: 8px 5px; }
.ly-deck .ly-seek { margin-left: 6px; }
.ly-time-combo {
  flex-shrink: 0; margin-left: 8px; font-family: var(--font-mono);
  font-size: 10px; color: var(--muted); white-space: nowrap;
}
.ly-time-combo i { font-style: normal; margin: 0 2px; opacity: .6; }
/* Rabbit seek thumb: inline SVG silhouette,
   颜色吃 --btn,和播放钮/进度线一个血——纯矢量,没有贴图色差问题 */
.ly-deck .ly-seek-thumb {
  width: 22px; height: 22px; border: none; border-radius: 0;
  background: none; box-shadow: none;
  color: var(--btn);
  display: flex; align-items: center; justify-content: center;
  transform: translate(-50%, -56%);
}
.ly-song-info { min-width: 0; flex: 1; }
.ly-song-name {
  font-size: 16.5px; font-weight: 700; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ly-song-artist { font-size: 12.5px; color: var(--ink-soft); margin-top: 3px; }
.ly-lines {
  position: relative;
  flex: 1 1 0; min-height: 0; overflow-y: auto; overflow-x: hidden;
  padding: clamp(56px, 18dvh, 150px) 24px clamp(72px, 22dvh, 180px);
  -webkit-mask-image: linear-gradient(transparent, black 20%, black 80%, transparent);
  mask-image: linear-gradient(transparent, black 20%, black 80%, transparent);
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  touch-action: pan-y;
  /* scroll-behavior:smooth 已撤 —— 自动跟随改走 glideLyricsTo() 的 lerp 惯性，
     两套一起开会打架（原生平滑会吃掉我们每帧写的 scrollTop）。 */
  scroll-padding-block: 42%;
}
.ly-loading, .ly-no-lyrics {
  text-align: center; color: var(--muted); padding: 40px 0; font-size: 13px;
}
/* 这里原本是：transition: … font-size .3s …  —— 卡顿的真凶。
   font-size 动画每帧都要重新排版整列歌词（还会连锁触发换行变化），
   移动端一路掉帧。damso 那种丝滑的底层规矩就一条：只动 transform 和 opacity，
   这两个走合成器，不碰布局。所以字号固定，大小差交给 scale。
   字重也不再跳（600↔500 会改变文字宽度 → 长句重新换行 → 整列抖），
   层次改由 opacity + 颜色 + 缩放三样一起给。 */
/* Centered lyrics layout.
   With centered text the transform-origin must be center too — keeping
   `left center` makes the active line lurch sideways when it scales up. */
.ly-line {
  padding: 7px 0; font-size: 15px; font-weight: 500;
  color: var(--ink); opacity: 0.3;
  text-align: center;
  transform: scale(0.92); transform-origin: center;
  transition: opacity var(--t-base) var(--ease-out),
              transform var(--t-base) var(--ease-out),
              color var(--t-base) var(--ease-out);
  cursor: pointer; line-height: 1.5;
}
.ly-line.active {
  opacity: 1; color: var(--accent);
  transform: scale(1.1);            /* ≈ 16.5px 的视觉，但没有一次重排 */
}
/* 居中版不要左侧那根标尺了（贴在左边缘会和居中的字脱节）。
   当下那句靠字号、颜色、亮度自己站出来就够 —— Apple Music 也是这么干的。 */
.ly-trans {
  font-size: 12px; opacity: 0.65; margin-top: 2px; font-weight: 400; color: var(--ink-soft);
}
.ly-line.active .ly-trans { opacity: 0.85; color: var(--accent-soft); }
/* ── Per-character lyric animation ──
   封面放大重糊铺满歌词页,再叠一层浅色纱保证文字可读。 */
/* Lyric lines opt out of native text selection: long-press belongs to line-sharing. */
.ly-line { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.ly-w { display: inline-block; white-space: pre; }   /* 词包字:英文单词不从中间拆行 */
.ly-ch { display: inline-block; white-space: pre; }  /* 平时就是普通字,激活才有戏 */
.ly-line.active .ly-ch {
  opacity: 0; animation: lyChar .34s cubic-bezier(.2,.8,.2,1) var(--d, 0ms) forwards;
}
@keyframes lyChar {
  /* 速度优化:不透明度在动画前 45% 拉满(文字尽快可读),位移把余下动作演完。
        Note: per-char filter:blur animations repaint every frame —
     翻译行加入后 30+ 个字同跑直接压垮手机——拆掉 blur,只动 transform 和 opacity,
     动效原则:只动 transform 和 opacity,不做逐帧重画的 filter 动画。 */
  0%   { opacity: 0; transform: translateY(.4em) rotate(3deg); }
  45%  { opacity: 1; }
  100% { opacity: 1; transform: none; }
}
/* ── 8-31 「接下来播」队列:播放条小牌 + 清单面板 ── */
.np-queue-btn {
  flex: 0 0 auto; border: 1px solid var(--line); border-radius: 999px;
  padding: 4px 10px; margin-right: 2px;
  background: var(--accent-tint); color: var(--accent);
  font: inherit; font-size: 11.5px; font-weight: 700; cursor: pointer;
}
.qv-item { display: flex; align-items: center; gap: 10px; padding: 10px 2px; border-bottom: 1px solid rgba(194,112,138,.12); }
.qv-cover { width: 42px; height: 42px; border-radius: 10px; flex: 0 0 auto; overflow: hidden; }
.qv-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.qv-info { flex: 1; min-width: 0; display: grid; }
.qv-info b { font-size: 13.5px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qv-info small { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qv-now {
  flex: 0 0 auto; border: 0; border-radius: 999px; padding: 6px 12px;
  background: var(--accent-tint); color: var(--accent);
  font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
}
.qv-del {
  flex: 0 0 auto; width: 26px; height: 26px; border: 0; border-radius: 50%;
  background: transparent; color: var(--muted); font-size: 13px; cursor: pointer;
}
/* ── In-player line chat bar ── */
.ly-chatline {
  position: sticky; bottom: 0; z-index: 5;
  margin: 8px 12px; padding: 10px 12px;
  background: var(--milk, rgba(255,250,253,.96)); border: 1px solid var(--line, #f1c3d7);
  border-radius: 16px; box-shadow: 0 8px 24px rgba(150, 86, 120, .16);
}
.ly-chatline[hidden] { display: none; }
.ly-chatline-quote {
  font-size: 12px; color: var(--accent, #c2708a); font-style: italic;
  margin-bottom: 8px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ly-chatline-row { display: flex; gap: 8px; align-items: center; }
.ly-chatline-input {
  flex: 1; min-width: 0; padding: 8px 12px; font: inherit; font-size: 13px;
  border: 1px solid var(--line, #f1c3d7); border-radius: 999px;
  background: #fff; color: var(--ink, #6b4a5c); outline: none;
}
.ly-chatline-send {
  flex: 0 0 auto; padding: 8px 14px; border: 0; border-radius: 999px;
  background: var(--accent, #c2708a); color: #fff6ee;
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.ly-chatline-close {
  flex: 0 0 auto; width: 28px; height: 28px; border: 0; border-radius: 50%;
  background: transparent; color: var(--muted, #9b7d8c); cursor: pointer;
}
.daily-reason {
  font-size: 9.5px; padding: 1px 6px; margin-left: 4px;
  border-radius: 999px; background: var(--accent-tint); color: var(--accent);
  vertical-align: 1px;
}
/* ── 8-31 晚 MV 放映厅 ── */
.mv-view {
  position: fixed; inset: 0; z-index: 140;
  background: #0b0910;
  display: flex; flex-direction: column;
}
.mv-view.hidden { display: none; }
.mv-top {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; padding-top: calc(env(safe-area-inset-top, 0px) + 14px);
  color: #f5edf7;
}
.mv-title { flex: 1; font-size: 14px; font-weight: 600; display: grid; }
.mv-title small { font-size: 11px; font-weight: 400; opacity: .7; }
.mv-qual {
  background: rgba(255,255,255,.1); color: #f5edf7;
  border: 1px solid rgba(255,255,255,.2); border-radius: 999px;
  padding: 4px 10px; font: inherit; font-size: 12px;
}
#mv-video { flex: 1; width: 100%; min-height: 0; object-fit: contain; background: #000; }
.ly-bottom { display: flex; align-items: center; gap: 8px; padding: 8px 20px; flex-shrink: 0; }
.ly-time { font-size: 10px; color: var(--muted); flex-shrink: 0; width: 32px; font-family: var(--font-mono); }
.ly-time-end { text-align: right; }
.ly-seek {
  flex: 1; height: 22px; cursor: pointer; position: relative; touch-action: none;
  display: flex; align-items: center;
}
.ly-seek-track {
  width: 100%; height: 4px;
  background: rgba(194, 112, 138, 0.18);
  border-radius: 999px; position: relative;
}
.ly-seek-fill {
  height: 100%; border-radius: 999px;
  background: var(--btn);
  transition: width 0.15s linear;
}
.ly-seek-thumb {
  position: absolute; top: 50%; width: 13px; height: 13px;
  background: #fff; border: 3px solid var(--accent); border-radius: 50%;
  transform: translate(-50%, -50%); pointer-events: none;
  box-shadow: 0 2px 8px rgba(152, 78, 104, 0.3);
}
.ly-controls {
  display: flex; align-items: center; justify-content: center; gap: 30px;
  padding: 8px 20px calc(var(--safe-bottom) + 16px); color: var(--accent);
  flex-shrink: 0;
}
.ly-play-btn {
  width: 54px; height: 54px; border-radius: 50%;
  background: var(--btn); color: #fff;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  border: none;
  box-shadow: 0 8px 22px rgba(152, 78, 104, 0.4);
  transition: transform var(--t-base) var(--ease-spring);
}
.ly-play-btn:active { transform: scale(0.92); }
.ly-skip-btn {
  background: none; border: none; color: var(--accent-soft);
  cursor: pointer; padding: 10px; border-radius: var(--r-full);
  transition: transform var(--t-base) var(--ease-spring);
}
.ly-skip-btn:active { transform: scale(0.9); }

@media (prefers-reduced-motion: reduce) {
  .lyrics-view, .ly-line, .ly-seek-fill { transition: none; }
  .ly-lines { scroll-behavior: auto; }
}

/* ── Song Memory Panel ── */
.memory-view {
  position: fixed; inset: 0; z-index: 110;
  display: flex; flex-direction: column;
  background: linear-gradient(168deg, #fff1f5 0%, #fff8ec 55%, #ffeff2 100%);
}
.memory-view.hidden { display: none; }
.sm-header {
  display: flex; align-items: center; gap: 10px; padding: 16px 20px;
  padding-top: calc(env(safe-area-inset-top, 0px) + 16px);
}
.sm-close {
  background: var(--milk); border: 1px solid var(--line); color: var(--rose-deep);
  font-size: 20px; cursor: pointer; padding: 0;
  width: 36px; height: 36px; border-radius: var(--r-full);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-sm);
}
.sm-header-title { font-size: 15px; font-weight: 600; color: var(--ink); flex: 1; }
.sm-refresh {
  background: var(--milk); border: 1px solid var(--line); color: var(--rose-deep);
  cursor: pointer; padding: 0; width: 36px; height: 36px; border-radius: var(--r-full);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-sm);
}
.sm-body { flex: 1; overflow-y: auto; padding: 0 20px 24px; }
.sm-feeling {
  font-size: 14px; line-height: 1.7; color: var(--ink);
  padding: 16px 18px; margin-bottom: 12px;
  background: linear-gradient(150deg, rgba(255, 237, 194, 0.7), rgba(255, 248, 230, 0.5));
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: 16px; border-left: 3px solid var(--accent-soft);
  box-shadow: var(--shadow-sm);
}
.sm-notes {
  font-size: 13.5px; line-height: 1.7; color: var(--ink);
  padding: 12px 14px; white-space: pre-wrap;
/* Notes are for reading: display existing notes as a card, not inside the input. */
  background: rgba(255, 255, 255, .55); border: 1px solid var(--line);
  border-radius: 14px; margin-bottom: 10px;
}
.sm-fav-title { font-size: 11.5px; color: var(--muted); padding: 6px 2px 2px; }
.sm-fav-lines { padding: 8px 0 12px; }
.sm-fav-line {
  font-size: 13px; color: var(--accent);
  padding: 6px 0 6px 12px;
  border-left: 2px solid rgba(194, 112, 138, 0.5);
  line-height: 1.5; font-style: italic;
}
.sm-meta {
  display: flex; flex-wrap: wrap; gap: 12px; padding: 12px 2px;
  font-size: 11px; color: var(--muted);
}
.sm-tags { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 0; }
.sm-tag {
  font-size: 11.5px; padding: 4px 12px; border-radius: var(--r-full);
  background: var(--accent-tint); color: var(--accent);
}
.sm-loading, .sm-empty {
  text-align: center; color: var(--muted); padding: 60px 0; font-size: 13px;
}
/* ── Notes editor + comments panel ── */
.sm-edit {
  width: 100%; box-sizing: border-box; margin: 10px 0 0;
  padding: 12px 14px; font: inherit; font-size: 13.5px; line-height: 1.7; color: var(--ink);
  background: var(--milk); border: 1px solid var(--line); border-radius: 14px;
  resize: vertical; outline: none;
}
.sm-edit:focus { border-color: var(--accent-soft); }
.sm-edit-tags { resize: none; }
.sm-save {
  display: block; margin: 12px auto 4px; padding: 9px 26px;
  font: inherit; font-size: 13px; font-weight: 600; color: #fff6ee;
  background: var(--accent); border: 0; border-radius: var(--r-full); cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.sm-save:disabled { opacity: .6; }
.cm-item {
  padding: 12px 2px 10px; border-bottom: 1px solid rgba(194, 112, 138, 0.12);
}
.cm-item.hot { background: linear-gradient(150deg, rgba(255,237,194,.28), transparent); border-radius: 12px; padding-inline: 10px; margin-bottom: 4px; border-bottom: 0; }
.cm-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.cm-ava { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; }
.cm-user { font-size: 12px; font-weight: 600; color: var(--rose-deep); }
.cm-hot-tag { font-size: 10px; padding: 1px 8px; border-radius: var(--r-full); background: var(--accent-tint); color: var(--accent); }
.cm-text { font-size: 13.5px; line-height: 1.7; color: var(--ink); white-space: pre-wrap; overflow-wrap: break-word; }
.cm-foot { display: flex; gap: 14px; margin-top: 6px; font-size: 11px; color: var(--muted); }
.cm-divider { text-align: center; font-size: 11.5px; color: var(--muted); padding: 16px 0 6px; }
.cm-more { margin-bottom: 20px; }


/* ── Toast ── */
.toast {
  position: fixed; top: 56px; left: 50%; transform: translateX(-50%);
  background: rgba(107, 74, 85, 0.95); color: #fff6ee; padding: 9px 20px; border-radius: 999px;
  font-size: 13px; font-weight: 600; z-index: 9000; pointer-events: none;
  box-shadow: 0 10px 26px rgba(107, 74, 85, 0.35); animation: fadeUp var(--t-fast) var(--ease-out);
  opacity: 0; transition: opacity var(--t-fast) var(--ease-out);
}
.toast.show { opacity: 1; }

/* ── 「切标签就好」提示条(2026-08-08)：原来这里是直接把播放器导航走，音乐必死。
   现在改成由用户选择：默认留在后台继续播放，需要跳转时主动按按钮。 ── */
.stuck-hint {
  position: fixed; left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 9100; display: flex; flex-direction: column; gap: 8px;
  background: rgba(107, 74, 85, 0.96); color: #fff6ee;
  padding: 13px 15px; border-radius: 16px; font-size: 13px; line-height: 1.6;
  box-shadow: 0 14px 34px rgba(60, 34, 44, 0.42);
  animation: fadeUp var(--t-fast) var(--ease-out);
}
.stuck-hint button {
  appearance: none; border: 1px solid rgba(255, 246, 238, 0.34); border-radius: 999px;
  background: transparent; color: #fff6ee; font: inherit; font-size: 12.5px;
  padding: 7px 12px; cursor: pointer;
}
.stuck-hint button[data-act="stay"] { background: rgba(255, 246, 238, 0.16); border-color: transparent; }
.stuck-hint button:active { transform: scale(.97); }

@keyframes fadeUp {
  from { opacity: 0; transform: translateX(-50%) translateY(8px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}
@keyframes spin { to { transform: rotate(360deg); } }
.spinner {
  width: 22px; height: 22px; border: 2.5px solid rgba(194, 112, 138, 0.2);
  border-top-color: var(--accent-soft); border-radius: 50%;
  animation: spin 0.6s linear infinite; margin: 34px auto;
}
/* ── 按压手感：按下去要跟手，松开要慢慢弹回来 ──
   这是「高级」和「廉价」的分界线。原来按下和松开共用一条 0.18s：
   按下慢半拍（像卡了），松开又太快（像弹簧断了）。
   现在两段分开 —— :active 期间用极短的 --t-press 立刻缩到位，
   手一松，规则失效，回弹走各自本来的 --t-base + --ease-spring（带一点过冲）。
   放在样式表最后，靠 :active 的特指度盖住前面各家自己的 transition。 */
button:active,
.nav-item:active,
.recent-row:active,
.song-row:active,
.pls-row:active,
.roam-pill:active {
  transition-duration: var(--t-press) !important;
  transition-timing-function: var(--ease-press) !important;
}

/* 列表行原本按下去毫无反应（只有按钮有）。加一层极轻的下沉，
   幅度必须小 —— 整行缩放太明显会晕。 */
.recent-row, .song-row, .pls-row {
  transition: transform var(--t-base) var(--ease-spring),
              background var(--t-fast) var(--ease-out);
}
.recent-row:active, .song-row:active, .pls-row:active { transform: scale(0.978); }

/* ── 拆卡片 ──
      Design pass: fewer nested cards, one glass container per view.
   每个元素都要一个白边 + 阴影 + 圆角的框装起来，框里再套框。
   实拍数到三层套娃：.song-list 一张大玻璃卡，里面每个 .pls-row / .recent-row
   又各是一张带边框和阴影的小卡 —— 一屏里能数出十几个「框」。
   damso 的做法是内容直接落在底上，靠间距、字号、留白分层，一个框都不画。

   下面把常驻的底色/描边/阴影全卸掉，只在手指真的碰到时才给一点回应。 */
/* Glass layout revision:
   .song-list 从卸妆名单里请回去——大盘子回归,行仍是无框平铺在盘内,
   「一张盘 + 平铺行」正是参考图的层级,不是 8-10 拆掉的那种三层套娃。 */
.home-card,
.recent-row,
.pls-row {
  background: none !important;
  border-color: transparent !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
/* 卸了底色，行与行就得靠间距分开，不然糊成一坨 */
.recent-list { gap: 2px; }
.pls-list { gap: 4px; }

/* 摸上去 / 按下去才浮出底色 —— 静止时干净，交互时有回应 */
@media (hover: hover) {
  .recent-row:hover, .pls-row:hover, .song-row:hover {
    background: rgba(255, 255, 255, 0.55) !important;
  }
}
.recent-row:active, .pls-row:active, .song-row:active {
  background: rgba(255, 255, 255, 0.66) !important;
}

/* 删除键别常驻瞪着人：平时半透明，碰到那一行才亮起来 */
.pls-row-del, .song-rm {
  opacity: 0.28;
  transition: opacity var(--t-fast) var(--ease-out);
}
@media (hover: hover) {
  .pls-row:hover .pls-row-del, .song-row:hover .song-rm { opacity: 0.75; }
}
