/* ============================================================================
 * 侧边栏样式 (Sidebar Styles)
 * 项目：有个电站 (JGgame)
 * 所有颜色使用 CSS 变量 (--color-*)
 * 
 * 功能：
 *   1. 侧边栏折叠/展开（.app-side 用 transform 滑出；占位列宽恒定、内容区域平移居中）
 *   2. 子菜单折叠/展开（高度动画，箭头旋转）
 *   3. 响应式：全程常显（左栏不再按宽度隐藏，见 responsive.css ①.4）
 *   4. 触摸设备优化
 * ========================================================================== */

/* ============================================================================
 * 布局容器（占位符，保持 grid 布局的列宽）
 * ========================================================================== */

/* 侧栏列：占位宽度（兜底 260px）。
   实际宽度分级在 responsive.css：≥1661=260 / 1200-1660=240 / ≤1199 隐藏；
   在此改数字不会生效，请改 responsive.css。 */
.app-side-col {
    grid-column: 1;
    grid-row: 1 / 3;
    width: 260px;
    min-width: 0;
    flex-shrink: 0;
    /* 占位列宽恒定（= 展开态）：折叠仅 .app-side 用 transform 滑出、内容块用 transform 平移居中，
       本列宽永不变 → 主区宽恒定、内容区零缩放零重排（居中规则见 style.css）。 */
}

/* 折叠态只覆盖宽度来源，值不变（var(--side-w) 即展开态宽度）。 */
.app-side-col.collapsed,
html.sidebar-collapsed .app-side-col {
    width: var(--side-w, 260px);
}

/* ============================================================================
 * 侧栏主体（固定定位，不随页面滚动）
 * ========================================================================== */

.app-side {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: 260px;             /* 宽度恒定；折叠仅用 transform 滑出，避免菜单内部反复重排导致卡顿 */
    background: var(--color-bg-sidebar);
    border-right: 1px solid var(--color-sidebar-border);
    /* 底部 12px：播放器自身有 12px 下内边距，两者叠加才是它离屏幕底的距离。
       ⚠️ 原来这里是 24px（2026-10-04 用户要求收到 12），别改回去 —— 会显得播放器吊在半空。 */
    padding: 84px 0 12px;
    overflow-y: auto;
    overflow-x: hidden;
    display: none;
    flex-direction: column;
    z-index: 100;
    transform: translateX(0);
    will-change: transform;
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 折叠状态：宽度恒定，仅 transform 把整块滑出视口左侧（GPU 合成，丝滑不重排） */
.app-side-col.collapsed .app-side,
html.sidebar-collapsed .app-side-col .app-side {
    transform: translateX(-100%);
}

/* 滚动条样式 */
.app-side::-webkit-scrollbar { width: 6px; }
.app-side::-webkit-scrollbar-track { background: transparent; }
.app-side::-webkit-scrollbar-thumb { 
    background: var(--color-border-strong); 
    border-radius: 3px; 
}
.app-side::-webkit-scrollbar-thumb:hover { background: var(--color-text-dim); }

/* ============================================================================
 * 分组与标题
 * ========================================================================== */

.app-side-group { display: block; margin: 0; }

.app-side-section-title {
    margin: 16px 24px 8px;
    padding: 0;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--color-sidebar-text-dim);
    opacity: 1;
}
.app-side-section-title:first-of-type { margin-top: 26px; }

/* ============================================================================
 * 菜单项
 * ========================================================================== */

.app-side-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    border-radius: 10px;
    font-size: 14px;
    font-weight: 500;
    margin: 2px 12px;
    color: var(--color-sidebar-text);
    text-decoration: none;
    transition: all 0.2s ease;
    cursor: pointer;
    position: relative;
    overflow: hidden;
}

/* Hover 效果：与选中(active)样式一致：浅色=黑色加粗文字，深色=金色文字 */
.app-side-item:hover,
.app-side-item.active:hover {
    background: transparent;
    color: var(--color-accent-ink);
    font-weight: 500;
    transform: none;
}
[data-theme="dark"] .app-side-item:hover,
[data-theme="dark"] .app-side-item.active:hover {
    color: var(--color-accent);
}

/* 选中状态：无背景，浅色=黑色加粗字体，深色=金色字体 */
.app-side-item.active {
    background: transparent;
    color: var(--color-accent-ink);
    font-weight: 500;
}
[data-theme="dark"] .app-side-item.active {
    color: var(--color-accent);
}

/* ============================================================================
 * 菜单图标
 * ========================================================================== */

.app-side-item .ic {
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: var(--color-sidebar-hover);
    font-size: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.2s ease, color 0.2s ease;
    flex-shrink: 0;
}

.app-side-item:hover .ic,
.app-side-item.active:hover .ic {
    background: var(--color-sidebar-hover);
    color: var(--color-accent-ink);
    transform: none;
}
[data-theme="dark"] .app-side-item:hover .ic,
[data-theme="dark"] .app-side-item.active:hover .ic {
    color: var(--color-accent-ink);
}

.app-side-item.active .ic {
    background: var(--color-sidebar-hover);
    color: var(--color-accent-ink);
    box-shadow: none;
}
[data-theme="dark"] .app-side-item.active .ic {
    color: var(--color-accent-ink);
}

/* ============================================================================
 * 菜单文本
 * ========================================================================== */

.app-side-item-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ============================================================================
 * 折叠箭头（有子菜单的项）
 * ========================================================================== */

.app-side-caret {
    font-size: 12px;
    opacity: 0.5;
    margin-left: auto;
    transition: transform 0.45s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.2s ease;
    flex-shrink: 0;
    color: var(--color-text-dim);
}

.app-side-item:hover .app-side-caret {
    opacity: 1;
    color: var(--color-accent);
}

/* 展开状态：箭头旋转 90° */
.app-side-group.expanded > .app-side-toggle-item .app-side-caret {
    transform: rotate(90deg);
}

.app-side-toggle-item { cursor: pointer; }

/* ============================================================================
 * 子菜单
 * ========================================================================== */

.app-side-children {
    /* 垂直外边距必须为 0：容器即使收起（高度 0）外边距也会占位，
       曾导致带子分类的顶级项下方多出 12px，顶级菜单间距不统一。
       垂直间距统一由 .app-side-item 自身的 margin 提供；水平 24px 保留（子项缩进）。
       收起/展开时垂直边距恒定，不影响 grid 动画。 */
    margin: 0 24px;
    padding: 0;
    border-left: none;
    /* 0fr ↔ 1fr：展开与收起共用同一条过渡，方向天然对称。
       不再用 JS 测量高度 + 强制重排驱动 height，避免起始值未提交导致的卡顿/提前展开，
       也不再需要监听 transitionend（子元素冒泡会提前收尾）。 */
    display: grid;
    grid-template-rows: 0fr;
    overflow: hidden;
    transition: grid-template-rows 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 展开态：只切一个类名；移除该类即反向播放同一条过渡，收起与展开完全一致 */
.app-side-group.expanded > .app-side-children {
    grid-template-rows: 1fr;
}

/* 内部包裹元素：网格项必须 min-height:0 才能被 0fr 压扁；overflow 负责裁剪内容 */
.app-side-children-inner {
    min-height: 0;
    overflow: hidden;
}

.app-side-subitem {
    display: flex;
    align-items: center;
    gap: 8px;
    /* 左缩进恒定 60px（对齐父级图标后的文字位置），不随展开切换 → 无跳变 */
    padding: 8px 14px 8px 60px;
    border-radius: 8px;
    font-size: 13px;
    margin: 1px 0;            /* 左右外边距改由 .app-side-children 统一提供，避免双重外边距 */
    color: var(--color-sidebar-text);
    text-decoration: none;
    transition: background 0.2s ease, color 0.2s ease, opacity 0.2s ease;
    cursor: pointer;
    opacity: 0.85;
}

.app-side-subitem:hover {
    background: var(--color-sidebar-hover);
    color: var(--color-accent);
    opacity: 1;
}

.app-side-subitem.active {
    background: var(--color-sidebar-active-bg);
    color: var(--color-accent-ink);
    font-weight: 500;
    opacity: 1;
}
[data-theme="dark"] .app-side-subitem.active {
    color: var(--color-sidebar-active-text);
}


/* ============================================================================
 * 折叠按钮（固定在侧边栏右侧边缘）
 * ========================================================================== */

.app-side-toggle-btn {
    position: fixed;
    top: 0;
    left: 260px;
    width: 22px;
    height: 100vh;
    background: transparent;
    border: none;
    border-radius: 0;
    cursor: pointer;
    z-index: 101;
    display: none;
    align-items: center;
    justify-content: center;
    color: #2196F3; /* 折叠按钮三点默认蓝——用户指定的侧边栏专属设计色，不随后台主题 */
    font-size: 18px;
    padding: 0;
    margin: 0;
    box-shadow: none;
    outline: none;            /* 删除刷新后浏览器恢复焦点产生的黑色描边 */
}

/* 任何焦点态都不显示轮廓（按钮已有 hover 蓝色背景反馈） */
.app-side-toggle-btn:focus,
.app-side-toggle-btn:focus-visible {
    outline: none;
}

.app-side-toggle-btn:hover {
    background: rgba(33, 150, 243, 0.08); /* 折叠按钮 Hover 淡蓝背景——用户指定设计色 */
    color: #1565C0; /* 折叠按钮 Hover 深蓝——用户指定设计色 */
    width: 22px;
    border-radius: 0;
    padding: 0;
    margin: 0;
    box-shadow: none;
}

/* 折叠按钮图标（三个点） */
.app-side-toggle-icon {
    width: 22px;
    height: 80px;
    background: transparent;
    border-radius: 0 2px 2px 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    font-weight: bold;
    letter-spacing: 2px;
    line-height: 1;
}

/* Hover 时三个点出现蓝色半透明背景 */
.app-side-toggle-btn:hover .app-side-toggle-icon {
    background: rgba(33, 150, 243, 0.2); /* 折叠按钮半透明蓝背景——用户指定设计色 */
}

/* 折叠状态：按钮移到左侧边缘（位置变化即为状态指示，无需旋转动画） */
.app-side-col.collapsed .app-side-toggle-btn,
html.sidebar-collapsed .app-side-col .app-side-toggle-btn {
    left: 0;
    border-radius: 0 10px 10px 0;
}

/* ============================================================================
 * 响应式样式（已收敛至 responsive.css）
 *   - 侧栏显隐断点              → responsive.css ①.4（≥1200px 显示）
 *   - 触摸 / 打印 / 减少动效     → responsive.css ⑫ 特性查询
 * 本文件仅保留桌面基础样式（.app-side 默认隐藏由 JS 控制折叠态）。
 * ========================================================================== */

/* 认证页面（登录/注册）隐藏侧边栏：由 responsive.css ①.4 的 ≤1199px 规则兜底 */


/* ============================================================
 * 从 style.css 迁移的移动端抽屉菜单样式
 * ============================================================ */

.app-drawer-mask { position: fixed; inset: 0; background: var(--overlay); z-index: 1500; opacity: 0; visibility: hidden; transition: opacity .25s ease; }
.app-drawer-mask.open { opacity: 1; visibility: visible; }
.app-drawer {
    position: fixed; top: 0; left: 0; bottom: 0; width: 280px; max-width: 82vw;
    background: var(--color-bg-sidebar); border-right: 1px solid var(--color-sidebar-border);
    z-index: 1600; transform: translateX(-100%); transition: transform .28s ease;
    display: none; flex-direction: column; padding: 12px 0 24px; overflow-y: auto;
}
.app-drawer.open { transform: translateX(0); }
.app-drawer-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 20px; border-bottom: 1px solid var(--color-sidebar-border); }
.app-drawer-title { font-size: 16px; font-weight: 700; color: var(--color-text-title); }
.app-drawer-close { border: none; background: transparent; color: var(--color-sidebar-text-dim); font-size: 22px; line-height: 1; cursor: pointer; padding: 0 6px; }
.app-drawer-body { padding: 12px 16px; flex: 1; }
.app-drawer-section { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }
.app-drawer-link { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: 12px; color: var(--color-sidebar-text); text-decoration: none; font-size: 15px; transition: all .2s; }
.app-drawer-link:hover { background: var(--color-sidebar-hover); color: var(--color-accent); }
.app-drawer-reward { padding: 16px; }


/* ============================================================================
 * 侧栏常驻音乐播放器（自研 UI，2026-10-04）
 *
 * 引擎是 APlayer（ap.play/seek/volume/on + ap.audio + ap.list），
 * 但 **DOM 与样式全部自绘，且不加载 APlayer.min.css**。
 * 原因：官方 CSS 里有 `.aplayer.aplayer-withlrc .aplayer-pic{height:90px}` 这类
 *   写死值 + 运行时注入 <head> 末尾，跟 240px 侧栏死冲突，只能靠 !important 压。
 *   不加载它就没有冲突源，进度条/切歌键/音量想放哪放哪。
 *
 * 结构（骨架在 view/layout/side.html，JS 只填数据不拼字符串）：
 *   .mp          纵向：封面行 + 歌单
 *   .mp-cover    90px 封面，中心叠播放/暂停按钮（hover / 键盘聚焦时显形）
 *   .mp-col      右列，竖排：歌名 → 歌手 → 进度条 → 时间 → 控制条
 *   .mp-ctl      上一首 · 下一首 · 音量图标 · 音量条 · 歌单开关
 *   .mp-list     歌单（默认折叠，限高由 data-list-height 下发）
 *
 * ⚠️ 右列净宽只有 ~115px（215 - 90 封面 - 10 gap），改控件尺寸前先想清楚放不放得下。
 *
 * 配色全部走主题变量，深浅色自动跟随（--color-sidebar-* 在 variables.css
 * 与 theme.css 里都有 [data-theme=dark] 定义），⛔ 禁写死色值。
 * ========================================================================== */

.app-side-music {
    margin-top: auto;          /* 钉到侧栏底部（.app-side 是 flex column） */
    flex-shrink: 0;
    padding: 10px 12px 12px;
    border-top: 1px solid var(--color-sidebar-border);
}
.app-side-music-title {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    margin-bottom: 8px;
    color: var(--color-sidebar-text-dim);
}
.app-side-music-status {
    margin-top: 6px;
    font-size: 11px;
    line-height: 1.4;
    text-align: center;
    color: var(--color-sidebar-text-dim);
}
.app-side-music-status:empty { display: none; }
.app-side-music[data-state="error"] .app-side-music-status { color: var(--color-danger); }

/* 加载占位：歌单接口返回前不显示空骨架（空封面 + 00:00 像坏了）。
   用 data-state 切换而非 JS 增删节点 —— 骨架是静态的，切换零成本。 */
.mp-loading {
    padding: 30px 0;
    text-align: center;
    font-size: 12px;
    color: var(--color-sidebar-text-dim);
}
.mp-loading:empty { display: none; }
.app-side-music[data-state="loading"] .mp { display: none; }
.app-side-music:not([data-state="loading"]) .mp-loading { display: none; }

/* ---------- 主体：封面 + 右列 ---------- */
/* 侧栏 240px 扣掉 .app-side-music 的左右 padding(12+12) 后净宽 215px；
   封面 90px + 列间距 10px → 右列 115px，所以这里的尺寸都比常规播放器小一档。
   ⚠️ 用 grid 而不是 flex+wrap：flex-wrap 遇到「第三项占满 100%」时换行判定很难预测
      （实测 90+10+99 仍被判成需要换行，导致右列被挤到第二行）。grid 的列宽是显式的。
   ⛔ 本段必须保持唯一 —— 历史上这里叠过一份 `display:flex; flex-direction:column`
      的旧定义（2026-10-04 清掉），它只是靠「后写覆盖」侥幸没生效，留着会误导改样式的人。 */
.mp {
    display: grid;
    grid-template-columns: 90px minmax(0, 1fr);   /* 固定封面列 + 弹性右列 */
    align-items: start;
    column-gap: 10px;
    row-gap: 8px;
}
.mp-col {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;               /* 必写：否则长歌名不截断会把 grid 轨道撑破 */
}

/* 封面：中心叠播放/暂停按钮（主操作放在最大的一块上） */
.mp-cover {
    position: relative;
    width: 90px;
    height: 90px;
    flex: 0 0 90px;
    align-self: flex-start;
    border-radius: 8px;
    background: var(--color-sidebar-hover);
    background-size: cover;
    background-position: center;
    /* 没加载到图时用主题色占位，不显示浏览器默认的破图 */
    background-image: none;
}
.mp-cover-play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    border-radius: 8px;
    /* 半透明遮罩：保证图标在浅色封面上也看得清 */
    background: rgba(0, 0, 0, .32);
    color: #fff;
    font-size: 18px;
    cursor: pointer;
    opacity: 0;
    transition: opacity .15s ease;
}
/* 鼠标在播放器区域内时显形；键盘聚焦也显（无障碍不能只靠 hover） */
.mp:hover .mp-cover-play,
.mp-cover-play:focus-visible { opacity: 1; }
.mp-cover-play:hover { background: rgba(0, 0, 0, .45); }
.mp-cover-play:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }

/* ---------- 歌名 / 歌手：过长时左右滚动（共用一套 marquee） ---------- */
/* 结构统一是「外层裁切 + 内层平移」：外层 overflow:hidden 裁掉溢出部分，
   内层 .mp-*-tx 由 JS 量出溢出宽度写进 --mp-marquee-shift 供 keyframes 用。
   ⛔ 别用 text-overflow:ellipsis 的老写法（那样永远看不到完整内容）。 */
.mp-name,
.mp-artist {
    overflow: hidden;
    white-space: nowrap;
}
.mp-name {
    font-size: 12px;
    line-height: 1.35;
    color: var(--color-sidebar-text);
}
.mp-artist {
    font-size: 10.5px;
    line-height: 1.35;
    color: var(--color-sidebar-text-dim);
}
/* 歌手为空时整行收起 —— ⛔ 不能用 :empty 判：包了一层 span 之后容器永远不空 */
.mp-artist.is-empty { display: none; }

.mp-name-tx,
.mp-artist-tx {
    display: inline-block;
    white-space: nowrap;
    will-change: transform;
}
/* 只有真溢出（JS 打上 is-overflow）才滚动；短文本保持静止 */
.mp-name.is-overflow .mp-name-tx,
.mp-artist.is-overflow .mp-artist-tx {
    /* 时长由 JS 按溢出距离算（见 side-music.js 的 MARQUEE_SPEED），
       保证长短文本的**移动速度一致**，而不是长名被迫滚得飞快。
       这里的 8s 只是 JS 没来得及算时的兜底值。 */
    animation: mp-marquee var(--mp-marquee-dur, 8s) linear infinite;
}
/* 鼠标悬停 / 键盘聚焦时暂停，方便读全内容 */
.mp-name:hover .mp-name-tx,
.mp-name:focus-within .mp-name-tx,
.mp-artist:hover .mp-artist-tx,
.mp-artist:focus-within .mp-artist-tx { animation-play-state: paused; }
/* 尊重系统的「减少动态效果」设置 */
@media (prefers-reduced-motion: reduce) {
    .mp-name.is-overflow .mp-name-tx,
    .mp-artist.is-overflow .mp-artist-tx { animation: none; }
}
/* ⛔ 位移终点必须是 JS 实测的溢出距离，不能写 translateX(-100%)：
      后者按内层**自身**宽度算，短溢出时会滚过头露出空白。
   ⚠️ 首尾停留压到 8%（JS 算出的时长约 7~14s，即 0.5~1.1s）：
      早先是 12% 且固定 13s，等于切歌后静止 1.56 秒才开始动，
      观感上「点了没反应」——用户 2026-10-04 就是这么报的「滚动没生效」。 */
@keyframes mp-marquee {
    0%, 8%             { transform: translateX(0); }
    50%, 58%           { transform: translateX(calc(var(--mp-marquee-shift, 0px) * -1)); }
    100%               { transform: translateX(0); }
}

/* ---------- 进度条 ---------- */
.mp-bar {
    position: relative;
    width: 100%;
    height: 4px;
    margin-top: 2px;
    border-radius: 2px;
    background: var(--color-sidebar-hover);
    cursor: pointer;
    touch-action: none;         /* 允许在进度条上横向拖动而不触发页面滚动 */
}
.mp-bar-loaded,
.mp-bar-played {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    border-radius: 2px;
    width: 0;
}
.mp-bar-loaded { background: var(--color-sidebar-hover); filter: brightness(.85); }
.mp-bar-played { background: var(--color-accent); }
.mp-bar-thumb {
    position: absolute;
    top: 50%;
    left: 0;
    width: 10px;
    height: 10px;
    margin: -5px 0 0 -5px;
    border-radius: 50%;
    background: var(--color-accent);
    opacity: 0;                 /* 静止时隐藏，hover/拖动才显形 */
    transition: opacity .15s ease;
    pointer-events: none;
}
.mp-bar:hover .mp-bar-thumb,
.mp-bar:focus-visible .mp-bar-thumb,
.mp-bar.is-dragging .mp-bar-thumb { opacity: 1; }
.mp-bar:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }

/* ---------- 时间 ---------- */
.mp-time {
    display: flex;
    justify-content: space-between;
    font-size: 10px;
    line-height: 1;
    color: var(--color-sidebar-text-dim);
    font-variant-numeric: tabular-nums;  /* 等宽数字，跳秒时不会左右抖 */
}

/* ---------- 控制条 ----------
   上一首 · 播放 · 下一首 · 音量 · 歌单，5 个键只有 115px：
   5×22 + 4×1(gap) = 114（刚好）。⛔ 再加键或放大盒子前先算这个数。
   盒子小所以字形要相对放大（14px 字在 22px 盒里视觉直径约 12px，才看得清）。 */
.mp-ctl {
    position: relative;
    display: flex;
    align-items: center;
    gap: 1px;
    margin-top: 1px;
}
/* ⚠️ 包裹层必须有：它给竖向音量浮层提供定位上下文，宽度等于音量按钮本身，
   浮层的 left:50% 才能对到按钮中心。
   ⛔ 别把 .mp-vol-bar 直接挂回 .mp-ctl —— 那 50% 是控制条 115px 的中心
   （2026-10-04 用户报「浮层没在音量按钮上方」，实测偏 22.5px）。 */
.mp-vol-wrap {
    position: relative;
    display: flex;
    flex: 0 0 auto;
}
.mp-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    flex: 0 0 auto;
    padding: 0;
    border: 0;
    border-radius: 6px;         /* 软圆角，不用 999 全圆 */
    background: transparent;
    color: var(--color-sidebar-text);
    font-size: 14px;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.mp-btn:hover { background: var(--color-sidebar-hover); color: var(--color-accent); }
.mp-btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.mp-btn[disabled] { opacity: .4; cursor: not-allowed; }
.mp-btn[disabled]:hover { background: transparent; color: var(--color-sidebar-text); }

/* 控制条里的播放键：跟其他键同尺寸但用主色，视觉上一眼能找到 */
.mp-play-btn.mp-btn { color: var(--color-accent); }

/* 音量图标：只负责开/关浮层，本身不切静音 */
.mp-vol-btn { width: 22px; height: 22px; font-size: 15px; }

/* ⚠️ 播放/音量图标的显隐**必须走 .is-hidden 类，不能用 HTML 的 hidden 属性**。
   实测（2026-10-04）：`<svg hidden>` 的 hidden 属性确实会设上，
   `getComputedStyle().display` 仍是 `block`、图标照样占 18px 显示着 ——
   UA 样式表的 `[hidden]{display:none}` 不适用于 SVG 元素，
   页面里也没有任何一条 CSS 规则命中它（探针逐条枚举确认 matched 为空）。
   结论：SVG 元素要显隐只能自己写 class。
   ⛔ 别"顺手"改回 hidden 属性：单测查 hidden 值会 PASS，但界面纹丝不动。 */
.mp-i-pause.is-hidden,
.mp-i-play.is-hidden,
.mp-i-mute.is-hidden,
.mp-i-vol.is-hidden { display: none; }

/* 音量：竖向浮层，收起时 height:0 完全不占位，展开时 56px。
   绝对定位挂在 .mp-ctl 上方，所以展开不会把控制条顶下去、也不会撑高侧栏。
   ⚠️ 这里⛔不能加 padding 做内缩：JS 用 getBoundingClientRect().height 反推比例，
   padding 会让「量到的高度」比轨道本身高，拖到最底算出 0.03 而不是 0。
   需要内缩就用 inset 的 box-shadow 或给 .mp-vol-fill 加左右 margin。 */
.mp-vol-bar {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 20;
    width: 8px;
    height: 0;
    border-radius: 4px;
    background: var(--color-sidebar-hover);
    cursor: pointer;
    touch-action: none;
    overflow: hidden;
    transition: height .18s ease;
}
.mp-vol-bar.is-open { height: 56px; }
/* 拖动中：跟到竖条外也要继续跟，浮层不能收 */
.mp-vol-bar.is-dragging { transition: none; }
.mp-vol-fill {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 0;                 /* JS 按音量写百分比，顶到顶是 100% */
    border-radius: 4px;
    background: var(--color-accent);
}
.mp-vol-bar:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* 歌单开关推到最右（flex:0 0 auto 保证不被压扁） */
.mp-list-btn { margin-left: auto; flex: 0 0 auto; }

/* ---------- 歌单 ---------- */
.mp-list {
    grid-column: 1 / -1;       /* ⛔ 必须跨两列：grid 默认会把第 3 项塞进第 1 列 */
    max-height: 200px;          /* JS 会用 data-list-height 的值覆盖（必须带 px） */
    overflow-y: auto;
    overscroll-behavior: contain;   /* 歌单滚到底不要连带滚整页 */
    border-top: 1px solid var(--color-sidebar-border);
}
.mp-list[hidden] { display: none; }
.mp-list-ol {
    margin: 0;
    padding: 4px 0;
    list-style: none;
}
.mp-list-li {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 6px;
    font-size: 11.5px;
    line-height: 1.3;
    color: var(--color-sidebar-text);
    cursor: pointer;
    border-radius: 6px;
}
.mp-list-li:hover { background: var(--color-sidebar-hover); }
.mp-list-li.is-current { color: var(--color-accent); }
.mp-list-idx {
    flex: 0 0 auto;
    width: 16px;
    text-align: right;
    color: var(--color-sidebar-text-dim);
    font-variant-numeric: tabular-nums;
}
.mp-list-li.is-current .mp-list-idx { color: var(--color-accent); }
.mp-list-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.mp-list-dur {
    flex: 0 0 auto;
    color: var(--color-sidebar-text-dim);
    font-variant-numeric: tabular-nums;
}

/* ---------- 侧栏折叠 / 特殊页隐藏 ---------- */
/* 侧栏折叠时只保留标题：侧栏被 transform 滑出视口，播放器还占位会留空隙 */
html.sidebar-collapsed .app-side-music .mp,
html.sidebar-collapsed .app-side-music .mp-loading,
html.sidebar-collapsed .app-side-music-status { display: none; }
html.sidebar-collapsed .app-side-music { padding-bottom: 12px; }
/* 登录/注册全屏页与会员中心不显示侧栏，播放器一并隐藏 */
.auth-fullscreen .app-side-music,
.member-center .app-side-music { display: none; }
