/* ===== 音乐：主页 / 歌单页 / 搜索页 / 播放器页 / 迷你条 / 弹窗层 ===== */
/* 设计与理由见 PROMPT/25_音乐页.md
 * 页壳自成一套，只复用 setting-api.css 的 .api-header / .api-back / .api-title /
 * .api-subtitle / .api-section-label / .api-modal 那一套 / .api-btn / .api-field-box /
 * .api-input / .api-range，因此本文件必须排在 setting-api.css 之后。
 * 本文件禁止出现 backdrop-filter 和 will-change，滑入只动 transform。 */
/* .mu-bar 也在这一组里：它是 #app 的直接子节点、不长在任何一张页里，
 * 漏掉它的表现是 .mu-bar.is-nav 那条 calc 取不到 --mu-nav-h，整条声明被丢掉，
 * 迷你条一声不响地压在底栏上 */
.mu-page,
.mu-list-page,
.mu-search-page,
.mu-player-page,
.mu-bar,
.mu-layer {
  /* setting-api.css 的复用件会读这几个变量，值必须与 .api-page 保持一致 */
  --card-radius: 20px;
  --card-radius-in: 5px;
  --card-gap: 2px;
  --card-bg: var(--c-surface-2);
  --press-bg: var(--c-surface-3);
  --field-h: 48px;
  --btn-h: 46px;

  /* 本页自己的几档 */
  --mu-fill: var(--c-surface);          /* 白底页上的浅灰块，与聊天页同一个道理 */
  --mu-fill-press: var(--c-surface-2);
  --mu-row-r: 14px;                     /* 歌曲行 / 歌单行的圆角 */
  --mu-cover-r: 12px;                   /* 小封面圆角，大封面另有一档 */
  --mu-bar-h: 72px;                     /* 迷你条整块占的高度，页面靠它留出底部空间 */
  /* 底栏不含安全区的那一段。迷你条抬到底栏之上时按它偏移，
   * 改了 .mu-nav 的内边距或图标尺寸，这个值要跟着改 */
  --mu-nav-h: 63px;
  /* 封面底：比行底 --mu-fill 深一档，方块才从行里浮出来。日夜都跟着变量走 */
  --mu-cover-bg: var(--c-surface-2);
}

/* ===== 三张平铺页的共同页壳 ===== */
/* 播放器页不在这一组：它是从下往上推的，见 .mu-player-page */
.mu-page,
.mu-list-page,
.mu-search-page {
  position: absolute;                   /* #app 是 position: relative，见 base.css */
  inset: 0;
  display: flex;
  flex-direction: column;
  background: var(--c-bg);              /* 必须不透明，完整盖住下面一层 */

  transform: translateX(100%);
  visibility: hidden;
  transition:
    transform 0.3s var(--ease),
    visibility 0s linear 0.3s;
}
.mu-page.show,
.mu-list-page.show,
.mu-search-page.show {
  transform: translateX(0);
  visibility: visible;
  transition:
    transform 0.3s var(--ease),
    visibility 0s;
}

.mu-page { z-index: 10; }               /* 一级页，与设置页 / 聊天页同级 */
.mu-list-page,
.mu-search-page { z-index: 11; }        /* 从主页点进来的两张二级页，互不重叠 */

/* 与聊天页接力时用：退场的一方直接消失，两页不做交叉动画 */
.mu-page.is-swap,
.mu-list-page.is-swap,
.mu-search-page.is-swap,
.mu-player-page.is-swap { transition: none; }

/* hidden 属性来自 UA 样式表，本文件里的 display 声明会盖掉它，补一条更高优先级的 */
.mu-page [hidden],
.mu-list-page [hidden],
.mu-search-page [hidden],
.mu-player-page [hidden],
.mu-layer [hidden] { display: none; }

/* ===== 顶栏 ===== */
.mu-header {
  flex: none;
  /* 安全区一律用加法，不能用 max() */
  padding: calc(12px + var(--sat)) 20px 0;
}

/* 与 .api-back 同款同尺寸，镜像到右边，标题仍然相对整页居中 */
.mu-round {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto 0;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: var(--c-text);                 /* reicon 内部用 currentColor */
  transition: transform 0.15s var(--ease), background var(--dur) var(--ease);
}

/* 两颗圆钮跟着本页的浅灰走：setting-api.css 给 .api-back 的是灰底页上的灰，
 * 搬到白底页上会显得脏，这里连返回键一起改 */
.mu-page .api-back,
.mu-list-page .api-back,
.mu-search-page .api-back,
.mu-round { background: var(--mu-fill); }
.mu-page .api-back:active,
.mu-list-page .api-back:active,
.mu-search-page .api-back:active,
.mu-round:active {
  transform: scale(0.88);
  background: var(--mu-fill-press);
}

/* ===== 滚动区 ===== */
.mu-body {
  flex: 1;                              /* .scroll-area 不带 flex: 1 */
  min-height: 0;
  padding: 0 20px calc(24px + var(--sab));
}
/* 迷你条浮在页面上，挂了这个类的页面要把最后一行让出来 */
.mu-list-page.is-bar .mu-body,
.mu-search-page.is-bar .mu-body {
  padding-bottom: calc(24px + var(--sab) + var(--mu-bar-h));
}

/* 主页底部有一条占文档流的底栏，安全区由它承担，这里不能再加一次 */
.mu-page .mu-body { padding-bottom: 24px; }
.mu-page.is-bar .mu-body { padding-bottom: calc(24px + var(--mu-bar-h)); }

/* ===== 主页的两个面板 ===== */
.mu-panel { display: none; }
.mu-panel.is-active { display: block; }

/* ===== 底栏 ===== */
/* 只长在主页上，两张二级页没有。与聊天页的 .ct-nav 同参数，两处并排看得出是同一台机器 */
.mu-nav {
  flex: none;
  display: flex;
  align-items: stretch;
  border-top: 1px solid var(--c-border);
  background: var(--c-bg);
  /* 安全区一律用加法，不能用 max() */
  padding: 6px 12px calc(6px + var(--sab));
}

.mu-nav-item {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 6px 0;
  color: var(--c-hint);
  transition: color var(--dur) var(--ease);
}
.mu-nav-item.is-active { color: var(--c-text); }
.mu-nav-item:active { color: var(--c-accent-dark); }

.mu-nav-label {
  font-size: var(--label-size);
  font-weight: var(--label-weight);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* ===== 封面 ===== */
/* 纯色底 + 一枚固定图标：曲目、歌单、「我喜欢」各一枚，见 js/music.js 的 MU_ICON_*。
 * 全站不用渐变，封面之间不做区分 */
.mu-cover {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--mu-cover-r);
  overflow: hidden;
  color: var(--c-hint);
  background: var(--mu-cover-bg);
}

/* 真实封面图。cover 保证不同比例的图都填满方块，加载失败时下面那层纯色底顶上 */
.mu-cover-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* 四种尺寸，宽高一起写死：封面是正方形，让它由内容撑开会在图片缺席时塌成一条 */
.mu-cover.is-xs { width: 40px; height: 40px; --mu-cover-r: 10px; }
.mu-cover.is-sm { width: 48px; height: 48px; }
.mu-cover.is-md { width: 96px; height: 96px; --mu-cover-r: 18px; }
.mu-cover.is-rail { width: 116px; height: 116px; --mu-cover-r: 18px; }
/* 播放器页那张：由容器剩下的高度决定边长，两头都封死 ——
 * 只写 width: 100% 的话，矮屏上封面会把下面的控制行整个挤出屏幕 */
.mu-cover.is-lg {
  width: auto;
  height: 100%;
  max-height: 320px;
  max-width: 100%;
  aspect-ratio: 1 / 1;
  --mu-cover-r: 28px;
}

/* ===== 成对图标：两个都渲染出来，靠 class 切 ===== */
/* 改 re-icon 的 icon 属性是否重渲染不由本项目控制，与 .api-eye 的睁眼 / 闭眼同一个做法 */
.mu-icon-pause,
.mu-icon-one { display: none; }
.is-playing .mu-icon-play { display: none; }
.is-playing .mu-icon-pause { display: inline-flex; }
.mu-ctrl-repeat.is-one .mu-icon-all { display: none; }
.mu-ctrl-repeat.is-one .mu-icon-one { display: inline-flex; }

/* ===== 竖着的三点 ===== */
/* 图标库里没有 more-v，只有 more-h，转 90° 得到。转角写在这个包一层的 span 上，
 * 不写在 <re-icon> 上 —— 它是自定义元素，内部实现随时可能改，转它不保险 */
.mu-more-v {
  display: flex;
  align-items: center;
  justify-content: center;
  transform: rotate(90deg);
}

/* ===== 每日推荐大卡 ===== */
/* 首页第一块，整张是一颗按钮：日期占左边一格，右边一枚深底播放圆钮。
 * 全站不用渐变，这里靠「深底日期块 + 浅底整卡」两档灰拉开层次 */
.mu-daily {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  margin-top: 20px;
  padding: 14px;
  text-align: left;
  border-radius: 20px;
  background: var(--mu-fill);
  transition: transform 0.15s var(--ease), background var(--dur) var(--ease);
}
.mu-daily:active {
  transform: scale(0.98);
  background: var(--mu-fill-press);
}

.mu-daily-date {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 16px;
  background: var(--c-text);
  color: var(--c-bg);
}

/* 日号用等宽数字：1 号与 30 号的宽度一样，卡片不会跟着日期左右跳 */
.mu-daily-day {
  font-size: 22px;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.mu-daily-mon {
  margin-top: 1px;
  font-size: var(--label-size);
  font-weight: var(--label-weight);
  line-height: 1.2;
  letter-spacing: 0.14em;
  opacity: 0.7;
}

.mu-daily-text {
  flex: 1;
  min-width: 0;
  display: block;
}

.mu-daily-name {
  display: block;
  font-size: var(--page-title-size);
  font-weight: 600;
  line-height: 1.25;
  color: var(--c-text);
}

.mu-daily-sub {
  display: block;
  margin-top: 4px;
  font-size: var(--row-value-size);
  line-height: 1.3;
  color: var(--c-sub);
}

/* 卡里唯一的深底圆点。它不是按钮 —— 整张卡才是，套一颗真按钮进去是非法结构 */
.mu-daily-go {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--c-text);
  color: var(--c-bg);
}

/* ===== 最近播放：横向卡片轨 ===== */
/* 整页禁止横向滚动，这一条是页内的独立滚动容器，两侧用负外边距让卡片贴到页边 */
.mu-rail {
  display: flex;
  gap: 12px;
  margin: 0 -20px;
  padding: 2px 20px 4px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  /* 必须与 padding-left 等值：吸附口默认贴的是容器内边缘，不认这段内边距，
   * 少了它页面一加载就会自己横滚 20px，把左侧那点留白吃掉、首卡贴死屏幕边 */
  scroll-padding-left: 20px;
  scrollbar-width: none;
}
.mu-rail::-webkit-scrollbar { display: none; }

.mu-rail-item {
  flex: none;
  width: 116px;
  padding: 0;
  text-align: left;
  scroll-snap-align: start;
  transition: transform 0.15s var(--ease);
}
.mu-rail-item:active { transform: scale(0.96); }

.mu-rail-name {
  display: block;
  margin-top: 8px;
  font-size: var(--row-name-size);
  font-weight: var(--row-name-weight);
  line-height: 1.3;
  color: var(--c-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mu-rail-sub {
  display: block;
  margin-top: 2px;
  font-size: var(--row-value-size);
  line-height: 1.3;
  color: var(--c-sub);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ===== 行：歌单行与歌曲行共用一套骨架 ===== */
/* 一组行之间留 1px 透出页面底色，与聊天页 / 设置页那套「组内相邻的角收小」同源，
 * 只是本页的行都是等高的窄行，首尾不再另收大角 */
.mu-rows {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.mu-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 64px;
  padding: 8px 12px;
  text-align: left;
  border-radius: var(--mu-row-r);
  background: var(--mu-fill);
  cursor: pointer;                      /* 歌曲行是 div 不是 button，指针得自己给 */
  transition: background var(--dur) var(--ease);
}
.mu-row:active { background: var(--mu-fill-press); }

.mu-row-main {
  flex: 1;
  min-width: 0;
  display: block;
}

.mu-row-name {
  display: block;
  font-size: var(--row-name-size);
  font-weight: var(--row-name-weight);
  line-height: 1.35;
  color: var(--c-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mu-row-sub {
  display: block;
  margin-top: 3px;
  font-size: var(--row-value-size);
  line-height: 1.3;
  color: var(--c-sub);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 行尾的时长：等宽数字，换歌不会让整列左右跳 */
.mu-row-time {
  flex: none;
  font-size: var(--label-size);
  color: var(--c-hint);
  font-variant-numeric: tabular-nums;
}

/* 行尾那颗「更多」：靶区 32，图标 16，与行的按压态分开 —— 点它不算点这一行 */
.mu-row-more {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: var(--c-hint);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.mu-row-more:active {
  background: var(--mu-fill-press);
  color: var(--c-text);
}

/* 正在播放的那一行：名字转深、封面上盖一层跳动的三根竖条。
 * 不给整行换底色 —— 行底本来就是浅灰，再深一档会和按压态撞上 */
.mu-row.is-now .mu-row-name {
  color: var(--c-text);
  font-weight: 600;
}
.mu-row.is-now .mu-row-sub { color: var(--c-accent-dark); }

/* 封面上的播放标记：右下角一枚小深底方章，里面三根竖条。
 * 不做成盖住整张封面的遮罩 —— 全站灰阶，一整块压暗会把封面本身抹平，
 * 116px 的最近播放卡上尤其像一块坏掉的灰砖。
 * 暂停时竖条停住而不隐藏：这枚章标的是「这首是当前曲目」，不是「正在响」 */
.mu-cover-now {
  position: absolute;
  right: 4px;
  bottom: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 18px;
  height: 18px;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.55);
}
.mu-cover-now i {
  display: block;
  width: 2px;
  height: 6px;
  border-radius: 1px;
  background: #ffffff;                  /* 压在深色小章上，跟着主题变会看不见 */
  animation: mu-eq 0.9s var(--ease) infinite alternate;
}
.mu-cover-now i:nth-child(2) { animation-delay: 0.3s; }
.mu-cover-now i:nth-child(3) { animation-delay: 0.15s; }
.mu-cover-now.is-paused i { animation-play-state: paused; }

@keyframes mu-eq {
  from { height: 3px; }
  to   { height: 10px; }
}

/* 小章跟着封面尺寸收放：18px 摆在 40px 的迷你条封面上会占掉近一半，
 * 摆在 116px 的最近播放卡上又小到看不出是什么 */
.mu-cover.is-xs .mu-cover-now {
  right: 3px;
  bottom: 3px;
  width: 14px;
  height: 14px;
  border-radius: 5px;
  gap: 1px;
}
.mu-cover.is-xs .mu-cover-now i { width: 1.5px; }


.mu-cover.is-rail .mu-cover-now,
.mu-cover.is-md .mu-cover-now {
  right: 8px;
  bottom: 8px;
  width: 24px;
  height: 24px;
  border-radius: 8px;
}

/* ===== 空状态 ===== */
/* 文案里的换行由 textContent 带进来，靠 pre-line 生效 */
.mu-empty {
  padding: 40px 24px;
  text-align: center;
  font-size: 14px;
  line-height: 1.6;
  white-space: pre-line;
  color: var(--c-hint);
}

/* 页脚那句说明：与收藏页的 .cf-note 同一档 */
.mu-note {
  margin-top: 22px;
  padding: 0 4px;
  font-size: var(--row-value-size);
  line-height: 1.6;
  text-align: center;
  color: var(--c-hint);
}

/* ===== 我的：名片 ===== */
/* 头像 + 昵称 + 签名一横排。头像本身就是编辑入口，不另摆一颗「编辑资料」按钮 ——
 * 顶栏右上那颗笔已经是同一件事，摆两个入口只会让人以为是两件事 */
.mu-me-card {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 20px;
}

.mu-me-face {
  flex: none;
  width: 72px;
  height: 72px;
  padding: 3px;
  border-radius: 50%;
  background: var(--mu-fill);
  transition: transform 0.15s var(--ease);
}
.mu-me-face img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  background: var(--mu-cover-bg);
}
.mu-me-face:active { transform: scale(0.95); }

.mu-me-text {
  flex: 1;
  min-width: 0;
}

.mu-me-nick {
  font-size: var(--page-title-size);
  font-weight: 600;
  line-height: 1.25;
  color: var(--c-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mu-me-sign {
  margin-top: 6px;
  font-size: var(--row-value-size);
  line-height: 1.4;
  color: var(--c-sub);
  /* 签名最多两行：再长就把分段条挤下去了 */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 还没填的那一档：占位文案压到最弱，一眼看得出是「空着」而不是内容 */
.mu-me-nick.is-empty,
.mu-me-sign.is-empty { color: var(--c-hint); }

/* ===== 我的：歌单 / 电台 ===== */
/* 分段卡槽借 setting-api.css 的 .api-tabs，这里只调它与名片之间的距离 */
.mu-me-tabs { margin-top: 22px; }

.mu-me-panel { display: none; }
.mu-me-panel.is-active { display: block; }

/* 列表与分段条之间留一档，与 .api-section-label 的上边距同高 */
.mu-me-panel > .mu-rows { margin-top: 18px; }

/* 新建歌单摆在列表末尾、整宽一颗：分段条右边塞不下加号，
 * 而「建一张新的」本来就该出现在已有的这些下面 */
.mu-me-add {
  width: 100%;
  margin-top: 12px;
}

/* 电台本期没有内容，只有一段空状态，上下留白由它自己给 */
.mu-me-panel .mu-empty { padding-top: 56px; }

/* ===== 扫码登录 ===== */
/* 二维码是中转直接回的 base64，底必须是纯白 —— 夜间模式下跟着主题变深会扫不出来，
 * 所以这一块是全文件唯一写死颜色的地方 */
.mu-qr-box {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 200px;
  height: 200px;
  margin: 6px auto 0;
  padding: 10px;
  border-radius: 18px;
  background: #ffffff;
}

.mu-qr-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* 取码期间的占位。压在白底上，同样不跟主题走 */
.mu-qr-load {
  font-size: var(--row-value-size);
  line-height: 1.4;
  text-align: center;
  color: #999999;
}

.mu-qr-tip {
  flex: none;
  padding: 14px 12px 2px;
  text-align: center;
  font-size: var(--row-name-size);
  line-height: 1.5;
  white-space: pre-line;
  color: var(--c-sub);
  /* 状态文案长短不一，固定两行高，卡片不会随状态跳动 */
  min-height: 2.6em;
}

/* ===== 编辑资料弹窗里的头像 ===== */
.mu-me-hero {
  flex: none;
  display: flex;
  justify-content: center;
  padding-bottom: 18px;
}

.mu-me-avatar {
  width: 92px;
  height: 92px;
  padding: 4px;
  border-radius: 50%;
  background: var(--c-bg);
  box-shadow: var(--shadow-sm);
  transition: transform 0.15s var(--ease);
}
.mu-me-avatar img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  background: var(--mu-cover-bg);
}
.mu-me-avatar:active { transform: scale(0.96); }

/* ===== 歌单详情页：头块 ===== */
.mu-hero {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 20px;
}

.mu-hero-text {
  flex: 1;
  min-width: 0;
}

.mu-hero-name {
  font-size: var(--page-title-size);
  font-weight: 600;
  line-height: 1.25;
  color: var(--c-text);
  /* 歌单名可以很长，这里是它唯一完整露面的地方，最多两行 */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.mu-hero-sub {
  margin-top: 6px;
  font-size: var(--row-value-size);
  line-height: 1.4;
  color: var(--c-sub);
}

.mu-hero-desc {
  margin-top: 4px;
  font-size: var(--row-value-size);
  line-height: 1.4;
  color: var(--c-hint);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* 播放全部 / 随机播放：等分一行，主按钮深底白字，与聊天名片上那两颗同形 */
.mu-hero-acts {
  display: flex;
  gap: 8px;
  margin-top: 18px;
}

.mu-act {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 42px;
  padding: 0 12px;
  border-radius: var(--r-pill);
  background: var(--mu-fill);
  font-size: var(--row-name-size);
  font-weight: var(--row-name-weight);
  color: var(--c-text);
  white-space: nowrap;
  transition: transform 0.15s var(--ease), background var(--dur) var(--ease);
}
.mu-act:active {
  transform: scale(0.97);
  background: var(--mu-fill-press);
}

/* 深底那颗不走 --c-accent-dark：中间那档灰在白底上压不住场 */
.mu-act.is-solid {
  background: var(--c-text);
  color: var(--c-bg);
}
.mu-act.is-solid:active { background: var(--c-title); }

/* 空歌单里那两颗按不动的：留在原位压暗，撤掉会让头块每次进出都改高度 */
.mu-act[disabled] {
  opacity: 0.4;
  pointer-events: none;
}

/* 曲目一首都没有时，空状态下面那颗「从曲库添加」 */
.mu-empty-act {
  width: 100%;
  max-width: 220px;
  margin: 16px auto 0;
}

/* ===== 搜索页 ===== */
.mu-search-box {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 46px;
  margin-top: 20px;
  padding: 0 16px;
  border-radius: 23px;
  background: var(--mu-fill);
  color: var(--c-hint);
}
.mu-search-box input {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  padding: 0;
  font-family: inherit;
  /* 必须 >= 16px，否则 iOS 一聚焦就把整页放大 */
  font-size: 16px;
  color: var(--c-text);
  -webkit-appearance: none;
  appearance: none;
}
.mu-search-box input::placeholder { color: var(--c-hint); }
.mu-search-box input::-webkit-search-decoration,
.mu-search-box input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* 输入框右侧的清空：有字才出现 */
.mu-search-clear {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--mu-fill-press);
  color: var(--c-sub);
  transition: transform 0.15s var(--ease);
}
.mu-search-clear:active { transform: scale(0.9); }

/* ===== 迷你播放条 ===== */
/* 浮在平铺页之上、播放器页之下。整块是一颗按钮，点哪儿都进播放器，
 * 右边两颗控制键自己吃掉点击 */
.mu-bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 12;
  padding: 0 12px calc(8px + var(--sab));
  /* 整块只是个定位壳，不接点击：它的 padding-bottom 把元素一直撑到屏幕底，
   * 而 z-index 比底栏高 —— 留着 auto 的表现是底栏被这段内边距整条盖死，
   * 播上歌之后 ME 那颗按钮就再也点不动。真正要接点击的是下面那颗 inner */
  pointer-events: none;
  transform: translateY(130%);
  visibility: hidden;
  transition:
    transform 0.3s var(--ease),
    visibility 0s linear 0.3s;
}
.mu-bar.show {
  transform: translateY(0);
  visibility: visible;
  transition:
    transform 0.3s var(--ease),
    visibility 0s;
}

/* 主页在最上时抬到底栏之上。安全区已经算在基础内边距里，这里只补底栏那一段 */
.mu-bar.is-nav { padding-bottom: calc(8px + var(--sab) + var(--mu-nav-h)); }

.mu-bar-inner {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 8px 8px 10px;
  border-radius: 18px;
  background: var(--c-surface-2);
  box-shadow: var(--shadow-md);
  overflow: hidden;                     /* 进度线要被圆角切住 */
  pointer-events: auto;                 /* 外壳是 none，点击靶区收在这一块上 */
}

/* 顶边那条进度线：整块唯一表示「走到哪儿了」的地方，宽度由 JS 写 --mu-p */
.mu-bar-prog {
  position: absolute;
  top: 0;
  left: 0;
  height: 2px;
  width: var(--mu-p, 0%);
  background: var(--c-accent-dark);
  transition: width 0.25s linear;       /* 与 MU_TICK 同步，走起来才是匀的 */
}

.mu-bar-art {
  flex: none;
  display: flex;
  cursor: pointer;
}

.mu-bar-text {
  flex: 1;
  min-width: 0;
  display: block;
  text-align: left;
}

.mu-bar-name {
  display: block;
  font-size: var(--row-name-size);
  font-weight: var(--row-name-weight);
  line-height: 1.3;
  color: var(--c-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mu-bar-sub {
  display: block;
  margin-top: 2px;
  font-size: var(--row-value-size);
  line-height: 1.3;
  color: var(--c-sub);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mu-bar-btn {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  color: var(--c-text);
  transition: transform 0.15s var(--ease), background var(--dur) var(--ease);
}
.mu-bar-btn:active {
  transform: scale(0.9);
  background: var(--c-surface-3);
}

/* ===== 播放器页 ===== */
/* 唯一一张从下往上推的页：它不是「更深一层」，而是把迷你条整块展开 */
.mu-player-page {
  position: absolute;
  inset: 0;
  z-index: 13;
  display: flex;
  flex-direction: column;
  background: var(--c-bg);

  transform: translateY(100%);
  visibility: hidden;
  transition:
    transform 0.32s var(--ease),
    visibility 0s linear 0.32s;
}
.mu-player-page.show {
  transform: translateY(0);
  visibility: visible;
  transition:
    transform 0.32s var(--ease),
    visibility 0s;
}

.mu-player-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 28px calc(20px + var(--sab));
}

/* 封面区自己吃掉多余的高度：矮屏上先压缩这里，控制区一行都不能少 */
.mu-player-art {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 12px 0;
}

/* 暂停时整块缩一点，是全页唯一的「停了」的体态提示 */
.mu-player-art .mu-cover {
  box-shadow: var(--shadow-lg);
  transition: transform 0.35s var(--ease);
}
.mu-player-page.is-paused .mu-player-art .mu-cover { transform: scale(0.94); }

.mu-player-meta {
  flex: none;
  width: 100%;
  text-align: center;
}

.mu-player-name {
  font-size: 22px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--c-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mu-player-sub {
  margin-top: 6px;
  font-size: var(--row-name-size);
  line-height: 1.3;
  color: var(--c-sub);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ===== 进度条 ===== */
/* 轨道直接用 setting-api.css 的 .api-range，填充比例走它的 --api-fill */
.mu-seek {
  flex: none;
  width: 100%;
  margin-top: 18px;
}

.mu-seek-time {
  display: flex;
  justify-content: space-between;
  margin-top: -6px;
  font-size: var(--label-size);
  color: var(--c-hint);
  font-variant-numeric: tabular-nums;
}

/* ===== 控制行 ===== */
.mu-ctrl {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  margin-top: 14px;
}

.mu-ctrl-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  color: var(--c-text);
  transition: transform 0.15s var(--ease), color var(--dur) var(--ease);
}
.mu-ctrl-btn:active { transform: scale(0.88); }

/* 随机与循环是两个开关：关着的时候压到最弱一档，开着才是正文色 */
.mu-ctrl-btn.is-toggle { color: var(--c-hint); }
.mu-ctrl-btn.is-toggle.is-on { color: var(--c-text); }

/* 播放键是整页唯一的深底块 */
.mu-ctrl-play {
  width: 64px;
  height: 64px;
  background: var(--c-text);
  color: var(--c-bg);
}
.mu-ctrl-play:active { background: var(--c-title); }

/* ===== 播放器底部三项 ===== */
.mu-player-foot {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
  margin-top: 16px;
  color: var(--c-hint);
}

.mu-foot-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  color: inherit;
  transition: transform 0.15s var(--ease), color var(--dur) var(--ease);
}
.mu-foot-btn:active { transform: scale(0.88); }
/* 「喜欢」开着时跳到正文色，与同一页的随机 / 循环两颗是同一档对比 ——
 * 全站不给彩色，也不换 filled 字重，这一跳就是唯一的开关信号，
 * 落在 --c-accent-dark 那一档太弱，看不出点没点上 */
.mu-foot-btn.is-on { color: var(--c-text); }

/* ===== 弹窗层 ===== */
/* 所有弹窗都挂在这一层，不挂在各自的页里 —— 单曲弹窗要能盖住主页、歌单页、
 * 搜索页和播放器页四张，挂在其中任何一张里都会被另外几张压住。
 * 关着的弹窗是 display: none，本层的 pointer-events 只是兜底 */
.mu-layer {
  position: absolute;
  inset: 0;
  z-index: 14;
  pointer-events: none;
}
.mu-layer .api-modal { pointer-events: auto; }

/* 弹窗里的单曲抬头：封面 + 名字 + 歌手。
 * .api-modal-card 是纵向 flex，卡里除列表外的每一块都要 flex: none，否则会被压扁 */
.mu-modal-song {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 14px;
}

.mu-modal-song-text {
  flex: 1;
  min-width: 0;
}

.mu-modal-song-name {
  font-size: var(--row-name-size);
  font-weight: var(--page-title-weight);
  line-height: 1.3;
  color: var(--c-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mu-modal-song-sub {
  margin-top: 3px;
  font-size: var(--row-value-size);
  line-height: 1.3;
  color: var(--c-sub);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 弹窗里的一列动作行：图标 + 文字，一行一件事。
 * 行数不定（单曲弹窗 3~4 行、歌单菜单 1~3 行），矮屏上让它自己滚，不撑破卡片。
 * 滚动行为由 HTML 上的 .scroll-area 提供，这里只管排布 */
.mu-opts {
  flex: 0 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--card-gap);
  overscroll-behavior: contain;
}

.mu-opt {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 50px;
  padding: 8px 16px;
  text-align: left;
  background: var(--card-bg);
  border-radius: var(--card-radius-in);
  color: var(--c-text);
  transition: background var(--dur) var(--ease);
}
.mu-opt:first-child {
  border-top-left-radius: var(--card-radius);
  border-top-right-radius: var(--card-radius);
}
.mu-opt:last-child {
  border-bottom-left-radius: var(--card-radius);
  border-bottom-right-radius: var(--card-radius);
}
.mu-opt:active { background: var(--press-bg); }

.mu-opt-ico {
  flex: none;
  display: flex;
  align-items: center;
  color: var(--c-accent-dark);
}

.mu-opt-name {
  flex: 1;
  min-width: 0;
  font-size: var(--row-name-size);
  font-weight: var(--row-name-weight);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mu-opt-side {
  flex: none;
  font-size: var(--row-value-size);
  color: var(--c-hint);
}

/* 已经做过的那一行：压暗并挡掉点击，位置留着，用户才看得出「它已经在里面了」 */
.mu-opt.is-idle {
  pointer-events: none;
  opacity: 0.45;
}

/* 弹窗里的滚动列表：与 .api-modal-list 同一个道理，滚动行为来自 HTML 上的 .scroll-area，
 * 这里只补一条 overscroll-behavior，滚到头不把滚动链传给背后的页面 */
.mu-modal-list {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--card-gap);
  overscroll-behavior: contain;
}

.mu-modal-tip {
  flex: none;
  padding: 26px 20px;
  text-align: center;
  font-size: 14px;
  line-height: 1.6;
  white-space: pre-line;
  color: var(--c-hint);
}

/* 删除确认那张卡里的一段话 */
.mu-modal-text {
  flex: none;
  padding: 2px 2px 16px;
  font-size: var(--row-name-size);
  line-height: 1.6;
  white-space: pre-line;
  color: var(--c-sub);
}

/* 新建 / 重命名歌单那张卡：两个字段之间的间距由字段自己给 */
.mu-name-field { flex: none; }
.mu-name-field + .mu-name-field { margin-top: 12px; }

.mu-name-label {
  margin: 0 0 8px 4px;
  font-size: var(--row-value-size);
  color: var(--c-sub);
}

/* 队列里当前这首：与列表里的做法一致，只转字色不换底 */
.mu-opt.is-now .mu-opt-name {
  color: var(--c-text);
  font-weight: 600;
}
.mu-opt.is-now .mu-opt-ico { color: var(--c-text); }

/* 减弱动态效果：取消位移与按压缩放，均衡器竖条停住 */
@media (prefers-reduced-motion: reduce) {
  .mu-page,
  .mu-page.show,
  .mu-list-page,
  .mu-list-page.show,
  .mu-search-page,
  .mu-search-page.show,
  .mu-player-page,
  .mu-player-page.show,
  .mu-bar,
  .mu-bar.show {
    transform: none;
    transition: visibility 0s;
  }
  .mu-cover-now i { animation: none; height: 9px; }
  .mu-bar-prog { transition: none; }
  .mu-player-art .mu-cover,
  .mu-player-page.is-paused .mu-player-art .mu-cover {
    transform: none;
    transition: none;
  }
  .mu-page .api-back:active,
  .mu-list-page .api-back:active,
  .mu-search-page .api-back:active,
  .mu-round:active,
  .mu-sec-btn:active,
  .mu-rail-item:active,
  .mu-act:active,
  .mu-daily:active,
  .mu-me-face:active,
  .mu-me-avatar:active,
  .mu-bar-btn:active,
  .mu-ctrl-btn:active,
  .mu-foot-btn:active,
  .mu-search-clear:active { transform: none; }
}
