/* ============================================================
   音乐馆（music.php · AllSongsView）—— 手写 CSS2
   inc/header.php 按页面名自动挂这一份（assets/css/p-music.css）。

   原版：src/app/music/page.tsx + src/components/music/songs-view.tsx 的 AllSongsView。
   下面每个数都是**量出来的**，不是照 Tailwind 名字推的：2026-09-23 用 Chrome 探针
   对着 127.0.0.1:3010/music 在 1395×939 下逐节点量了一遍（内容区 98..1282，
   宽 1184），注释里 [x,y,w,h] 就是那次的读数。

   ★ 本页用到的手艺（style.css 里都有实测记录）：
     · 一行里「定宽 + 自适应 + 定宽」→ display:table / table-cell
     · 等分列 → 浮动 + 百分比宽度（列间距用 padding 补，容器用负 margin 抵）
     · grid 的 gap → 表格用 border-spacing（**首尾也各留一份**，所以要
       width: calc(100% + 2×gap) + margin-left: -gap 把两侧那两条抵掉，
       见 .ui-grid3 与下面 .mu-lrowt 的算式）；浮动栅格用 padding
     · 正方形封面 → 百分比 padding-top（IE 没有 aspect-ratio），用 .cov-sq
     · 悬浮蒙层 → :hover 改后代 opacity（IE 认任意元素的 :hover）
     · 居中一律「算好的外边距 / 绝对定位 + 负 margin」，不靠行高和 vertical-align
       （原版所有 svg 都是 display:block —— Tailwind preflight 的
        `svg{display:block;vertical-align:middle}`，所以行盒不会被 svg 撑高，
       我们这边要自己写 display:block）
     · **flex 的 gap 在 IE 是 0**：所有间距都写成 margin/padding/border-spacing
   ============================================================ */

/* ---- 页内容区：原版 space-y-7 pb-6 ----
   量到的竖向节奏：hero[88..232] → 精选[260..394] → 筛选[422..456] → 曲库[484..]，
   每两节之间正好 28（space-y-7 = 7×4）。
   用 `> * + *` 而不是给每个孩子写 margin-top：第一项不能有上边距。 */
.mu-stack > * + * { margin-top: 28px; }
.mu-stack { padding-bottom: 24px; }

/* ============================================================
   一、顶部氛围区：relative rounded-2xl overflow-hidden  →  [98,88,1184,144]
   ============================================================ */
.mu-hero { position: relative; border-radius: 16px; overflow: hidden; }   /* rounded-2xl = 1rem */

/* bg-gradient-to-br from-[#5B8FA8] via-[#4E7F97] to-[#3C6478]
   （to bottom right = 135deg，三个色标各占 0/50/100） */
.mu-hero-bg {
  position: absolute; left: 0; top: 0; right: 0; bottom: 0;
  background: linear-gradient(135deg, #5B8FA8 0%, #4E7F97 50%, #3C6478 100%);
}
/* 两团光斑：原版是 25% 白的圆 + blur-3xl(64px)。IE 没有 filter: blur，
   改用「径向渐变到透明」复刻柔边（.cov-blob-a 同一套办法）。 */
.mu-hero-blobs { position: absolute; left: 0; top: 0; right: 0; bottom: 0; opacity: 0.4; }
.mu-blob-a {
  position: absolute; top: -64px; right: -40px; width: 288px; height: 288px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.25) 0%, rgba(255,255,255,0) 70%);
}
.mu-blob-b {
  position: absolute; bottom: -96px; left: 25%; width: 256px; height: 256px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(143,184,201,0.4) 0%, rgba(143,184,201,0) 70%);
}
/* 斜放的唱片：hidden md:block → 默认不出，≥768 才出来。
   旋转写在外层 div 上而不是 svg 上：IE11 对 svg 根元素的 CSS transform 不可靠。 */
.mu-hero-disc {
  display: none; position: absolute; right: -32px; bottom: -48px;
  width: 224px; height: 224px; color: rgba(255,255,255,0.1);
  transform: rotate(12deg);
}
.mu-hero-disc svg { display: block; width: 224px; height: 224px; }

/* 内层：relative p-6 md:p-8 flex flex-col md:flex-row md:items-center gap-6
   → 表格两格（左自适应 / 右按钮），竖直居中；gap-6(24) 落在右格的 padding-left */
.mu-hero-in { position: relative; padding: 24px; }
.mu-hero-row { display: table; width: 100%; border-collapse: separate; border-spacing: 0; }
.mu-hero-main { display: table-cell; vertical-align: middle; }
.mu-hero-act {
  display: table-cell; vertical-align: middle; white-space: nowrap;
  width: 1%; padding-left: 24px;
}

/* 图标块：w-16 h-16 md:w-20 md:h-20 rounded-2xl bg-white/15 border border-white/25
        shadow-lg backdrop-blur（IE 没有 backdrop-filter，半透明白底照旧，
        最外层那张渐变卡本来也够糊）
   内层 flex items-center gap-4 md:gap-5 → 表格两格：
     [图标格 64/80] [文字格 padding-left 16/20]
   图标格里的 svg 用**算好的外边距**居中（不要绝对定位：position:relative 在
   table-cell 上不生效，见 tplSongCard 那段注释）：
     64 格 → (64−2边框−32)/2 = 15，加 1 边框 = 距外沿 16
     80 格 → (80−2−36)/2 = 21，加边框 = 22 ✓ 量到 [152,142,36,36] */
.mu-hero-tile { display: table; border-collapse: separate; border-spacing: 0; }
.mu-hero-ico {
  display: table-cell; vertical-align: middle; text-align: center;
  width: 64px; height: 64px; border-radius: 16px;
  background-color: rgba(255,255,255,0.15);
  border: 1px solid rgba(255,255,255,0.25);
  box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);   /* shadow-lg */
}
.mu-hero-ico svg { display: block; width: 32px; height: 32px; margin: 15px auto; color: #FFFFFF; }
.mu-hero-txt { display: table-cell; vertical-align: middle; padding-left: 16px; }  /* gap-4 */
/* 标题量到 text-2xl（24/32）→ md:text-3xl（30/36）；副标题 text-[13px]，
   行高是继承来的 1.5（原版 text-[13px] 只给字号，行高走 html 的 line-height:1.5）
   → 19.5，量到 20 [230,172,182,20] */
.mu-hero-h1 { font-size: 24px; line-height: 32px; font-weight: bold; color: #FFFFFF; }
.mu-hero-p { margin-top: 8px; font-size: 13px; line-height: 1.5; color: rgba(255,255,255,0.85); }

/* 播放全部：h-10 px-3 gap-2 rounded-md(10) text-sm(14) border-white/30 bg-white/20
   ★ 内边距是 12 不是 20：原版类名里写着 px-5，但还有一条 has-[>svg]:px-3，
     选择器权重更高（.has-…:has(>svg) 两个类 vs .px-5 一个类），实测
     computed padding 就是 12px、按钮宽 106 [1144,140,106,40]。
     图标 16px 绝对定位在 left 12；文字左沿 = 12+16+8 = 36。 */
/* 上下内边距写 8、行高 22（= 内容盒高度）：参照版是 flex 居中，量到的
   padding 就是 8/12，文字盒落在 150..170。照这个写法字心也在 160，一模一样。 */
.mu-hero-btn {
  position: relative; display: inline-block;
  height: 40px; line-height: 22px; padding: 8px 12px 8px 36px;
  border: 1px solid rgba(255,255,255,0.3); border-radius: 10px;
  background: rgba(255,255,255,0.2); color: #FFFFFF;         /* 用 background 简写兜掉按钮的系统外观 */
  font-size: 14px; font-weight: 500; cursor: pointer;
  transition: background-color 0.15s cubic-bezier(0.4,0,0.2,1);   /* transition-all */
}
.mu-hero-btn:hover { background-color: rgba(255,255,255,0.3); }
.mu-hero-btn[disabled] { opacity: 0.5; cursor: default; }          /* disabled:opacity-50 */
.mu-hero-btn svg {
  position: absolute; left: 12px; top: 50%; margin-top: -8px;
  width: 16px; height: 16px; fill: currentColor;
}

/* ============================================================
   二、精选热播：flex items-center gap-2 mb-3 + grid-cols-1 sm:grid-cols-3 gap-4
   量到：标题行 [98,260,1184,24]、卡片行 [98,296,1184,98]（卡高 98）
   ============================================================ */
/* gap-2(8) 落在每格自己身上（表格单元的外边距不生效，只能用 padding）。
   ★ 图标、标题、副标题各占一格，但**标题自己不能当格子**：格子上的 padding 会长在
     它自己的矩形里（h2 的盒子会左移 8、宽 8），实测就报出 [114,260,72,24] 对不上
     参照版的 [122,260,64,24]。所以标题外面套一层 mu-sechd-h 出那 8 的间距，
     里面的 h2 是普通块、正好填满格子的内容盒 —— 三个盒子与参照版逐个重合。 */
.mu-sechd { display: table; margin-bottom: 12px; border-collapse: separate; border-spacing: 0; }
.mu-sechd > * { display: table-cell; vertical-align: middle; }
.mu-sechd-ico { width: 16px; }
.mu-sechd-ico svg { display: block; width: 16px; height: 16px; color: #608DA4; }
.mu-sechd-h { padding: 0 8px; }
.mu-sechd-t { font-size: 16px; line-height: 24px; font-weight: bold; color: #111C22; }
/* 副标题：参照版报出的是 [194,264,120,16] —— x=194 是标题那格的**右内边距**给的
   （标题格 = 8 + 64 + 8，右端正好 194），所以副标题这格自己不能再加左内边距，
   否则会推出 8 像素（实测 202）。
   纵向上参照版是个 flex 居中的 16 高盒子，落在格子顶部 +4 处。这里做成
   「行内块 + 上外边距 4」，靠 vertical-align:top 让它的**外边距盒**顶对齐格子顶部，
   于是文字盒正好在 +4；格子里的空白文本节点由 font-size:0 掐成 0 宽。 */
.mu-sechd-s { vertical-align: top; font-size: 0; line-height: 0; }
.mu-sechd-sub {
  display: inline-block; vertical-align: top; height: 16px; margin-top: 4px;
  font-size: 12px; line-height: 16px; color: #616B70;
}

/* grid-cols-1 sm:grid-cols-3 gap-4 → 浮动栅格（3 列时每张卡 384 宽：
   容器 −8 两边撑到 1200，每列 33.3333% = 400 − 16 padding = 384 ✓）。
   下边距 −16 是收回最后一排 padding-bottom 的尾巴，不然这一节比原版高 16。 */
/* ★ 外边距只能写长写：这里要是写 `margin: 0 -8px -16px`，那条简写里的 margin-top:0
   会和 .mu-stack 的 `> * + *`（同为 0,1,0 特指度、但它在前面）抢，简写在后就赢，
   下面整节会整体上移 28 像素（实测歌曲区 456 对参照版 484）。 */
.mu-featgrid { margin-left: -8px; margin-right: -8px; margin-bottom: -16px; }
.mu-featgrid:after { content: ""; display: table; clear: both; }
.mu-featcol { float: left; width: 100%; padding: 0 8px 16px; }
@media (min-width: 640px) { .mu-featcol { width: 33.3333%; } }   /* sm:grid-cols-3 */

/* 卡：group relative flex items-center gap-4 p-3 rounded-2xl border bg-card
       hover:shadow-lg hover:-translate-y-0.5 transition-all overflow-hidden
   高 98 = 1边框 + 12内边距 + 72封面 + 12 + 1边框 [98,296,384,98]。
   table-layout:fixed 是为了给文字列一个**确定宽度**，歌名才能截断
   （flex 那边靠 min-w-0，表格这边靠定宽 + 块级 span 上的 ellipsis）。 */
.mu-fcard {
  position: relative; display: table; table-layout: fixed; width: 100%;
  padding: 12px; border: 1px solid #D9DFE2; border-radius: 16px;
  background-color: #FAFCFD; cursor: pointer; overflow: hidden;
  transition: box-shadow 0.15s cubic-bezier(0.4,0,0.2,1),
              transform 0.15s cubic-bezier(0.4,0,0.2,1);
}
.mu-fcard:hover {
  box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);
  transform: translateY(-2px);                                     /* hover:-translate-y-0.5 */
}
.mu-fcard-cov { display: table-cell; vertical-align: middle; width: 88px; }   /* 72 + gap-4(16) */
.mu-fcard-tx { display: table-cell; vertical-align: middle; }
/* 封面外面那层只为了给悬浮蒙层当参照物（.cov 自己也是 relative，但它带
   overflow:hidden，蒙层放进去会被圆角裁掉） */
.mu-fcov { position: relative; width: 72px; height: 72px; }
.mu-fcard-mask {
  position: absolute; left: 0; top: 0; right: 0; bottom: 0;
  border-radius: 16px; background-color: rgba(0,0,0,0.45);
  opacity: 0; transition: opacity 0.15s cubic-bezier(0.4,0,0.2,1);
}
.mu-fcard:hover .mu-fcard-mask { opacity: 1; }
.mu-fcard-mask svg {
  position: absolute; left: 50%; top: 50%; margin: -12px 0 0 -12px;
  width: 24px; height: 24px; fill: #FFFFFF;
}

/* 名次行：flex items-center gap-1.5
   ★ 这里**不能用表格**：参照版的名次只有 20 宽（量到 [199,310,20,28]，歌名从
     225 起），表格会把最后一列推到格子右端，歌名就跟名次分家了。
     用「行内块 + line-height:0」复刻 flex：名次定宽 20、歌名紧跟、皇冠再紧跟，
     长的才截断（max-width 预留皇冠那 20）。 */
/* ★ font-size:0 是必须的，不是保险：行内块之间的换行是个空白文本节点，
     它按**容器的字号**占宽（14px 下 4 像素）—— 参照版是 flex，空白节点不生成
     匿名项，所以歌名从 225 起，而我们不掐掉就是 229。每个孩子都自带字号。 */
.mu-fro { white-space: nowrap; overflow: hidden; font-size: 0; line-height: 0; }
.mu-frank-n {
  display: inline-block; vertical-align: middle; width: 20px;   /* 实测「01」的宽度 */
  font-size: 18px; line-height: 28px; font-weight: 900; font-style: italic;
  font-variant-numeric: tabular-nums;
}
.mu-frank-1 { color: #608DA4; }                                    /* text-primary */
.mu-frank-2 { color: #FF6900; }                                    /* orange-500：oklch→sRGB，见 style.css:1989 */
.mu-frank-3 { color: #E17100; }                                    /* amber-600，同上 */
.mu-fname {
  display: inline-block; vertical-align: middle; margin-left: 6px;   /* gap-1.5 */
  max-width: calc(100% - 46px);                                      /* 名次 20 + 间距 6 + 皇冠 14 + 间距 6 */
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 14px; line-height: 20px; font-weight: 600;
}
.mu-fro-crown { display: inline-block; vertical-align: middle; margin-left: 6px; width: 14px; height: 14px; color: #B8740A; }
.mu-fmeta {
  margin-top: 4px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;   /* mt-1 */
  font-size: 12px; line-height: 16px; color: #616B70;
}
/* 播放量那一行：text-[11px] + 12 的播放图标 + gap-1 —— 图标绝对定位，
   行内 svg 会把行盒撑高（.sec-head-more 踩过）。行高 1.5 → 16.5，量到 17。 */
.mu-fplays {
  position: relative; margin-top: 6px; padding-left: 16px;
  font-size: 11px; line-height: 1.5; color: #616B70;
}
.mu-fplays svg { position: absolute; left: 0; top: 50%; margin-top: -6px; width: 12px; height: 12px; }

/* ============================================================
   三、筛选 / 排序 / 看法
   flex flex-wrap items-center gap-x-4 gap-y-3
   量到：整行 [98,422,1184,34]；左（胶囊）[98,425,965,28]；
   右 [1079,422,203,34] = 排序 [1079,427,129,24] + gap-3(12) + 切换 [1220,422,62,34]。
   ★ 行高 34 是**右边那组**撑出来的（切换器 1边框+2内边距+28按钮+2+1边框 = 34），
     胶囊只是竖直居中（425 = 422 + (34−28)/2）→ 所以左边格
     vertical-align:middle 正好落在这个位置。
   ============================================================ */
/* ★ 这里**不能**用 table-layout:fixed：右格写的 width:1% 会被当成 1%×1184 = 12 的死数，
     里面的排序组（203）会溢出到容器外面。auto 布局下 1% 只是「尽量窄」的建议，
     实际取 min-content = 16 + 203 = 219，左格拿到剩下的 965 —— 与读数逐像素一致。 */
.mu-filters { display: table; width: 100%; border-collapse: separate; border-spacing: 0; }
.mu-genres { display: table-cell; vertical-align: middle; font-size: 0; line-height: 0; }
.mu-sortcol {
  display: table-cell; vertical-align: middle; width: 1%; white-space: nowrap;
  padding-left: 16px;                                            /* gap-x-4 */
}

/* 风格胶囊：px-3 h-7 rounded-full text-xs
   量到 [98,425,48,28]（「全部」= 12内边距 + 24文字 + 12）、同行间距 6（gap-1.5）、
   胶囊高 28。
   ★ 行内块的**外边距盒**才是参与行盒计算的那块：胶囊上带着 6 的下外边距时，
     行盒就是 28+6 = 34 —— 正好等于整行高度，vertical-align:middle 没地方可居中，
     胶囊就顶到了 422（实测）。所以 6 的下外边距只在**会换行**的窄屏上给
     （见文件末尾 max-width:767px 那段），宽屏这行永远排得下、只有一行。 */
.mu-chip {
  display: inline-block; vertical-align: top; height: 28px; line-height: 28px;
  padding: 0 12px; margin: 0 6px 0 0; border-radius: 9999px;
  font-size: 12px; color: #616B70; background-color: rgba(230,236,239,0.6);   /* bg-muted/60 */
}
.mu-chip:hover { background-color: #E6ECEF; color: #111C22; }
.mu-chip-on, .mu-chip-on:hover { background-color: #608DA4; color: #FCFCFC; font-weight: 500; }

/* 排序：flex items-center gap-1 text-xs，各项 px-1.5 py-1 rounded(4)，
   中间夹一个 text-border 的「·」。
   参照版实测：三个选项各 36 宽（6+24+6），「·」3 宽，间隔是
     35.7 +4 +[2.67 +4 +35.7] +4 +[2.67 +4 +35.7] = 128.4 → 整块 129。
   也就是「·」左右各 4 —— 写成格子的 padding: 0 4px（**不要**用 `> * + *` 的
   padding-left：那样「·」后面那 4 就没了，整块只有 121）。 */
.mu-sorts { display: table; border-collapse: separate; border-spacing: 0; font-size: 12px; line-height: 16px; }
.mu-sorts > * { display: table-cell; vertical-align: middle; }
.mu-sortsep { padding: 0 4px; color: #D9DFE2; }
.mu-sortlink {
  display: block; padding: 4px 6px; border-radius: 4px; color: #616B70;
  transition: color 0.15s cubic-bezier(0.4,0,0.2,1);
}
.mu-sortlink:hover { color: #111C22; }
.mu-sortlink-on, .mu-sortlink-on:hover { color: #608DA4; font-weight: 500; }

/* 右半边：排序 + 切换，gap-3(12)；同一张表里放两个格子，
   竖直居中由 table-cell 给（行内块 + vertical-align 会差一两像素）。 */
.mu-sortbar { display: table; margin-left: auto; border-collapse: separate; border-spacing: 0; }
.mu-sortcell { display: table-cell; vertical-align: middle; padding-right: 12px; }
.mu-viewcell { display: table-cell; vertical-align: middle; }

/* 列表/网格切换：rounded-lg border(1) p-0.5(2) + 两个按钮 p-1.5(6) + 16 图标
   量到整块 62×34、按钮各 28×28 [1223,425,28,28]、图标 16 [1229,431,16,16]
   → 2+6+16+6+2 = 28，加边框和内边距 = 34 ✓ 两个格子 = 62 ✓。
   ★ 原版这两个是图标按钮（lucide list / layout-grid）——本页也照做，
     只是外层是 <a>（视角存在 URL 里，服务端渲染，不是客户端 state）。 */
.mu-views {
  display: table; border: 1px solid #D9DFE2; border-radius: 12px; padding: 2px;
  border-collapse: separate; border-spacing: 0;
}
.mu-vbtn { display: table-cell; vertical-align: middle; padding: 6px; border-radius: 10px; color: #616B70; }
.mu-vbtn:hover { color: #111C22; }
.mu-vbtn-on, .mu-vbtn-on:hover { background-color: rgba(96,141,164,0.1); color: #608DA4; }  /* bg-primary/10 */
.mu-vbtn svg { display: block; width: 16px; height: 16px; }

/* 空状态：rounded-2xl border border-dashed border-border py-20 text-center text-sm */
.mu-empty {
  border: 1px dashed #D9DFE2; border-radius: 16px; padding: 80px 0;
  text-align: center; font-size: 14px; line-height: 20px; color: #616B70;
}

/* ============================================================
   四、曲库（网格）
   grid-cols-2 sm:3 md:4 lg:5 xl:6 gap-4，断点与 .pl-col 一致（640/768/1024/1280）。
   量到 1395（xl）时 6 列、卡 184 宽、列距 16、卡高 236
   = 184 封面 + 8(mt-2) + 44(两行文字)。
   ============================================================ */
/* 同 .mu-featgrid：外边距写长写，把 margin-top 让给 .mu-stack 的 28。 */
.mu-grid { margin-left: -8px; margin-right: -8px; margin-bottom: -16px; }
.mu-grid:after { content: ""; display: table; clear: both; }
/* ★ 33.3333% / 16.6667% 这类除不尽的百分比，IE 只认到两位小数（实测 16.6667% 按
   16.66% 算）：1395 下容器 1200，一列 Chrome 200.0004、IE 199.92，一张卡差 0.08，
   六列 0.48 —— 肉眼看不出来，但**整页高度会因此差 1 像素**（8 排卡片 × 0.08 = 0.64），
   底下的区块跟着上移 1px。三份比对里这 1px 只出现在「高度」上（x 和宽度都还是
   90/290/… 与 184），看到就当 IE 的百分比精度差，别当错位。 */
.mu-col { float: left; width: 50%; padding: 0 8px 16px; }
@media (min-width: 640px)  { .mu-col { width: 33.3333%; } }
@media (min-width: 768px)  { .mu-col { width: 25%; } }
@media (min-width: 1024px) { .mu-col { width: 20%; } }
@media (min-width: 1280px) { .mu-col { width: 16.6667%; } }

.mu-gcard { cursor: pointer; }
/* 悬浮蒙层要盖在封面上（inset-0 相对 .relative 那层），所以套一层定位框 */
.mu-gcov { position: relative; }
.mu-gmask {
  position: absolute; left: 0; top: 0; right: 0; bottom: 0;
  border-radius: 16px; background-color: rgba(0,0,0,0.45);
  opacity: 0; transition: opacity 0.15s cubic-bezier(0.4,0,0.2,1);
}
.mu-gcard:hover .mu-gmask { opacity: 1; }
.mu-gmask svg {
  position: absolute; left: 50%; top: 50%; margin: -16px 0 0 -16px;
  width: 32px; height: 32px; fill: #FFFFFF;
}
/* 时长角标：bottom/right 1.5(6) px-1.5 py-0.5(6/2) rounded(4) text-[10px] bg-black/45
   量到 [246,643,30,19] = 行高 15 + 上下 2 + 2 ✓（10×1.5 = 15） */
.mu-dur {
  position: absolute; right: 6px; bottom: 6px; padding: 2px 6px; border-radius: 4px;
  font-size: 10px; line-height: 1.5; color: rgba(255,255,255,0.95);
  background-color: rgba(0,0,0,0.45); font-variant-numeric: tabular-nums;
}
/* 会员角标：top/left 1.5(6) rounded(4) bg-[#B8740A]/90 text-[10px] + 12 的皇冠，
   图标与文字之间 gap-0.5(2)：图标绝对定位在 left 6，文字从 6+12+2 = 20 起 */
.mu-vipbadge {
  position: absolute; left: 6px; top: 6px; padding: 2px 6px 2px 20px; border-radius: 4px;
  font-size: 10px; line-height: 1.5; color: #FFFFFF; background-color: rgba(184,116,10,0.9);
}
.mu-vipbadge svg { position: absolute; left: 6px; top: 50%; margin-top: -6px; width: 12px; height: 12px; }

/* 卡片底部：mt-2(8) flex items-start gap-1
   量到：文字块 [98,676,158,44]、收藏 [260,676,22,22]（右贴边、顶部对齐）。
   158 = 184 − 22 − 4(gap-1)，所以「文字格 padding-right: 4」+「收藏格 22」。
   ★ 文字块 44 高不是 36：原版的歌手是个 <button>（行内块），落在 24 高的行盒里
     （继承的 line-height: 24），所以第二行占 24 而不是 16 —— 卡片总高 236 靠的就是它。
     照搬：歌手那一行写成 line-height: 24px。 */
.mu-gmeta { display: table; table-layout: fixed; width: 100%; margin-top: 8px; border-collapse: separate; border-spacing: 0; }
.mu-gtxt { display: table-cell; vertical-align: top; padding-right: 4px; }
.mu-gfav { display: table-cell; vertical-align: top; width: 22px; text-align: right; }
.mu-gname {
  display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 14px; line-height: 20px; font-weight: 500; color: #111C22;
  transition: color 0.15s cubic-bezier(0.4,0,0.2,1);
}
.mu-gcard:hover .mu-gname { color: #608DA4; }
/* 歌手这一行：参照版是个行内块 <button>，文字盒实测 [98,701,158,16] —— 歌名底
   696 再往下 5。用「上 5 / 下 3 的外边距 + 16 的行高」复刻：块高 24（20+24 = 44，
   卡片总高 236 靠的就是这 44），而**量出来的矩形**正好是 [98,701,158,16]，
   和参照版逐像素相同（写成 padding-top:5px + height:24px 时字是对的，
   但报出来的是 24 高、y 差 5，比对报告里会留下一条假差异）。 */
.mu-gart {
  display: block; height: 16px; margin-top: 5px; margin-bottom: 3px;
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 12px; line-height: 16px; color: #616B70;
}
.mu-gart:hover { color: #608DA4; }
/* 收藏心：p-1(4) rounded-full + 14 的心（量到按钮 22×22、图标在 +4/+4）。
   未收藏时只在悬浮时露出来（group-hover:opacity-100），已收藏恒显且变主色 ——
   .is-fav 由 app.js 的 paintFavStates 挂，全局那条
   .is-fav{color:#608DA4} + .is-fav > svg{fill:currentColor} 正好吃得到。 */
/* 三个收藏/播放按钮都要先把浏览器的默认外观抹掉：IE 给 <button> 的默认内边距是
   1px 6px、边框 1px，还有个系统灰底（不抹的话悬停底色和 22/28 的盒子尺寸全不对）。 */
.mu-fav {
  display: inline-block; padding: 4px; border: 0; background: transparent;
  border-radius: 9999px; color: #616B70; opacity: 0;
}
.mu-fav svg { display: block; width: 14px; height: 14px; }
.mu-gcard:hover .mu-fav { opacity: 1; }
.mu-fav.is-fav { opacity: 1; }
.mu-fav:hover { background-color: #E6ECEF; }

/* ============================================================
   五、曲库（列表）
   原版：grid grid-cols-[44px_1fr_92px_118px_64px_40px] gap-3 px-3
   量到（容器内宽 1182）：表头 [99,485,1182,38]、行 [99,523,1182,57]，
   六条轨道落在 [111][167][919][1023][1153][1229]，1fr = 740
   = 1182 − 24(两侧 px-3) − 418(定宽) − 60(5 条 12 的列距)。

   ★ 表格这一侧：border-spacing **首尾也各留一份**（6 格 = 7 个间隔 = 84），
     首尾那两条正好就是 px-3 的 12 —— 表格铺满容器内宽（1182）时，
     第一列自动从 99+12 = 111 起、最后一列到 1269 止，与读数逐个对上。
     列宽账：1182 − 84(间隔) − 358(五条定宽和) = **740** = 1fr ✓
     （注意**不要**再给外层加一边 12 的 padding、表格再补 calc(100% + 24px)：
       那样表格成了 1158，第一列会落到 123，整排右移 12。）
   ★ 窄屏缩成 4 条轨道（44 / 1fr / 64 / 40）：两条 md: 以下的列 display:none，
     表格结构不动。
   ★ <button> 不能直接当 table-cell（IE 对按钮的 display 有额外限制，tplSongCard
     那段有记录），所以收藏按钮外面套了一层格子。
   ★ 固定列宽必须 table-layout:fixed —— auto 布局下 118 那条会被专辑长名撑开。 */
.mu-lv { border: 1px solid #D9DFE2; border-radius: 16px; background-color: #FAFCFD; overflow: hidden; }
.mu-lrowt {
  display: table; table-layout: fixed; width: 100%;
  border-collapse: separate; border-spacing: 12px 0;
}
.mu-lrowt > * { display: table-cell; vertical-align: middle; overflow: hidden; }
/* 行高（上下内边距）写在**格子上**：格子上的纵向 padding 不参与列宽计算，
   写在真正承载内容的那一格能让行高由内容撑出来（数据行 = 8+40+8+1 = 57）。 */
.mu-lrowt > .mu-lp8 { padding-top: 8px; padding-bottom: 8px; }
.mu-lrowt > .mu-lp10 { padding-top: 10px; padding-bottom: 10px; }

/* 表头：hidden md:grid → 默认不显示，≥768 才出来。
   高 38 = 10 + 17 + 10 + 1(下边框)；17 是 11×1.5 的取整。 */
.mu-lhead {
  display: none; border-bottom: 1px solid #D9DFE2;
  font-size: 11px; line-height: 1.5; color: #616B70;
}
.mu-c-idx { width: 44px; text-align: center; }
.mu-c-song { width: auto; }
.mu-c-gen { width: 92px; }
.mu-c-alb { width: 118px; }
.mu-c-dur { width: 64px; text-align: right; }
/* ★ 这一格必须把行盒掐成 0（font-size/line-height:0），再让按钮 vertical-align:top：
   不然按钮是行内块、按**基线**落位，而「按钮里套一个 svg」的基线两个引擎算法不同 ——
   实测 Trident 里按钮报 534（对 537）、图标 540（对 543），Chrome 里却正好。
   掐成 0 之后行盒 = 按钮的外边距盒 28，格子 vertical-align:middle 把它居中到
   531 + (40−28)/2 = 537 —— 两个引擎都落这儿（同 .mu-genres 那套配方）。 */
.mu-c-fav { width: 40px; text-align: center; font-size: 0; line-height: 0; }

/* 数据行：py-2 + 下边框（最后一行没有）+ hover:bg-muted/50
   ⚠ 这里是**每行一张表**（表头一张、每首歌一张）—— 外层 div 只管边框和底色，
     横向那 12 由表格自己的 border-spacing 出，所以外层不能有左右 padding。
   高 57 = 8 + 40(封面) + 8 + 1 */
.mu-lrow { border-bottom: 1px solid rgba(217,223,226,0.6); cursor: pointer; }
.mu-lrow:hover { background-color: rgba(230,236,239,0.5); }
/* ★ 最后一行**保留**那条 1px 下边框 —— 这是照着参照版实测抄的，不是漏删：
   参照版最后一行的类名里明明有 `last:border-0`，但 computed 量出来仍是
   border-bottom: 1px rgba(...,0.6)（那条变体在实际 DOM 里没生效）。于是它那一行
   是 57 高、整个容器 2760；我们要是把最后一行的边框去掉，容器就成了 2759、
   底部分隔线只剩页脚自己的那 1px（实测 foot.1 3201 对 3202、box.3 2759 对 2760）。
   照抄实测值：所有行都带下边框，最后一行与页脚的上边框并排成 2px 的浅灰线。 */

/* 序号 / 悬浮变播放键：同一格里两件东西，:hover 换显 */
.mu-lidx-n {
  display: block; font-size: 14px; line-height: 20px; color: #616B70;
  font-variant-numeric: tabular-nums;
}
/* 「悬浮变播放键」：两个都是 svg / span **自己**带类名（icon() 把类名挂在 svg 上），
   所以选择器不能写成 `.mu-lidx-play svg`。 */
.mu-lidx-play { display: none; width: 16px; height: 16px; margin: 0 auto; color: #608DA4; fill: currentColor; }
.mu-lrow:hover .mu-lidx-n { display: none; }
.mu-lrow:hover .mu-lidx-play { display: block; }

/* 歌曲那一格：flex items-center gap-3 → 封面 40 + gap 12 + 文字
   （量到封面 40，文字块从 219 起 = 167 + 40 + 12） */
.mu-lsong { display: table; table-layout: fixed; width: 100%; border-collapse: separate; border-spacing: 0; }
.mu-lcov { display: table-cell; vertical-align: middle; width: 52px; }
.mu-ltx { display: table-cell; vertical-align: middle; }

/* 歌名那一行：flex items-center gap-1.5 —— 同「精选热播」，不能用表格
   （参照版里「高品质」徽标紧跟歌名：歌名 42 宽 + 6 + 徽标 40 = 88 = 文字块宽）。
   量到：歌名 [219,533,42,20]、徽标 [267,534,40,17]。 */
.mu-lnm { white-space: nowrap; overflow: hidden; font-size: 0; line-height: 0; }
.mu-lnname {
  display: inline-block; vertical-align: middle; max-width: calc(100% - 66px);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;   /* 皇冠 14+6 与徽标 40+6 的余量 */
  font-size: 14px; line-height: 20px; font-weight: 500; color: #111C22;
}
.mu-lnname:hover { color: #608DA4; text-decoration: underline; }
.mu-lnm-crown { display: inline-block; vertical-align: middle; margin-left: 6px; width: 14px; height: 14px; color: #B8740A; }
/* 高品质：text-[10px] text-primary border border-primary/40 rounded(4) px-1
   —— 量到徽标本体 40×17 = 2边框 + 8内边距 + 30文字（三个汉字 × 10）
   hidden lg:inline → ≥1024 才出现 */
.mu-lhi { display: none; margin-left: 6px; }
.mu-lhi > span {
  display: inline-block; vertical-align: middle; padding: 0 4px;
  border: 1px solid rgba(96,141,164,0.4); border-radius: 4px;
  font-size: 10px; line-height: 15px; color: #608DA4; white-space: nowrap;
}
.mu-lmeta {
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 12px; line-height: 16px; color: #616B70;
}
.mu-lartlink { color: #616B70; }
.mu-lartlink:hover { color: #608DA4; }
.mu-lalb { display: inline; }
.mu-lgen, .mu-lalbum {
  display: none; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: 12px; line-height: 16px; color: #616B70;
}
.mu-ltime {
  font-size: 12px; line-height: 16px; color: #616B70; text-align: right;
  font-variant-numeric: tabular-nums;
}
/* 收藏：p-1.5(6) rounded-full + 16 的心 —— 量到按钮 28×28，在 40 宽的轨道里居中
   （1229 + (40−28)/2 = 1235 ✓）。显隐规则同网格卡。 */
.mu-lfav {
  display: inline-block; vertical-align: top; padding: 6px; border: 0; background: transparent;
  border-radius: 9999px; color: #616B70; opacity: 0;
}
.mu-lfav svg { display: block; width: 16px; height: 16px; }
.mu-lrow:hover .mu-lfav { opacity: 1; }
.mu-lfav.is-fav { opacity: 1; }
.mu-lfav:hover { background-color: #E6ECEF; }
/* 到底了那一行：px-3 py-3 text-[11px] 居中 + 上边框
   量到 [99,3202,1182,42] = 12 + 17 + 12 + 1 */
.mu-lfoot {
  padding: 12px 0; border-top: 1px solid #D9DFE2; text-align: center;
  font-size: 11px; line-height: 1.5; color: #616B70;
}

@media (min-width: 768px) {
  .mu-lhead { display: block; }
  .mu-lgen, .mu-lalbum { display: table-cell; }
  .mu-lalb { display: none; }        /* md:hidden：窄屏并到歌手后面的那张专辑名 */
}
@media (min-width: 1024px) {
  .mu-lhi { display: inline-block; }
}

/* ============================================================
   六、电台那一排（tplScrollRow）
   ⚠ 结构差异（已知）：原版把电台放在**独立视图**里（other-views.tsx 的
     DjradioView，带分类筛选和私人 FM），/music 上根本没有这一节；我们这个
     PHP 版把它简化成一排 140 宽的卡挂在音乐馆底部。
   ★ .srow-track 上写了 font-size:0 / line-height:0，所以卡片必须自带
     字号**和行高**（只写字号会继承 0 行高，字全叠在一起）。 */
.mu-rd { width: 140px; font-size: 14px; line-height: 20px; cursor: pointer; }
.mu-rdcov { position: relative; }
.mu-rdmask {
  position: absolute; left: 0; top: 0; right: 0; bottom: 0;
  border-radius: 16px; background-color: rgba(0,0,0,0.4);
  opacity: 0; transition: opacity 0.15s cubic-bezier(0.4,0,0.2,1);
}
.mu-rd:hover .mu-rdmask { opacity: 1; }
/* 40×40 白色圆按钮 + 16 的播放键（图标右移 2 让三角形看着居中：ml-0.5） */
.mu-rdplay {
  position: absolute; left: 50%; top: 50%; margin: -20px 0 0 -20px;
  width: 40px; height: 40px; border-radius: 50%; padding: 0; border: 0;
  background: rgba(255,255,255,0.95); cursor: pointer;
  box-shadow: 0 20px 25px -5px rgba(0,0,0,0.1), 0 8px 10px -6px rgba(0,0,0,0.1);   /* shadow-xl */
  transition: transform 0.15s cubic-bezier(0.4,0,0.2,1);
}
.mu-rdplay:hover { transform: scale(1.1); }
.mu-rdplay svg {
  position: absolute; left: 50%; top: 50%; margin: -8px 0 0 -6px;
  width: 16px; height: 16px; fill: #111C22; color: #111C22;
}
/* 曲目数角标：top-2 right-2(8) px-1.5 py-0.5(6/2) rounded(4) bg-black/50 */
.mu-rdcnt {
  position: absolute; right: 8px; top: 8px; padding: 2px 6px; border-radius: 4px;
  font-size: 10px; line-height: 1.5; color: #FFFFFF; background-color: rgba(0,0,0,0.5);
}
.mu-rdn { margin-top: 8px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
          font-size: 14px; line-height: 20px; font-weight: 500; color: #111C22; }
.mu-rdd { overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
          font-size: 12px; line-height: 16px; color: #616B70; }

/* ============================================================
   七、md 断点：原版这几处是「并排」→「上下堆叠」/ 放大一号
   桌面（1395）才是这一页的主场景，窄屏保证不塌。
   ============================================================ */
@media (min-width: 768px) {
  .mu-hero-in { padding: 32px; }                                   /* md:p-8 */
  .mu-hero-ico { width: 80px; height: 80px; }                      /* md:w-20 h-20 */
  .mu-hero-ico svg { width: 36px; height: 36px; margin: 21px auto; }   /* md:w-9 h-9 */
  .mu-hero-txt { padding-left: 20px; }                             /* md:gap-5 */
  .mu-hero-h1 { font-size: 30px; line-height: 36px; }              /* md:text-3xl */
  .mu-hero-disc { display: block; }                                /* hidden md:block */
}
@media (max-width: 767px) {
  .mu-hero-row, .mu-hero-main, .mu-hero-act, .mu-hero-tile, .mu-hero-txt { display: block; }
  .mu-hero-act { width: auto; padding-left: 0; padding-top: 24px; }   /* flex-col + gap-6 */
  .mu-hero-txt { padding-left: 0; padding-top: 16px; }
  /* 竖排时按钮撑满一行、内容居中（flex-col 的 align-items:stretch）：
     图标改回行内，绝对定位在窄屏会跟居中文字错开 */
  .mu-hero-btn { display: block; width: 100%; text-align: center; padding: 0 12px; }
  .mu-hero-btn svg { position: static; display: inline-block; width: 16px; height: 16px; margin: 0 8px -3px 0; }
  /* 筛选区：flex-wrap 到窄屏就是上下两段（gap-y-3 = 12） */
  .mu-filters, .mu-genres, .mu-sortcol { display: block; width: auto; }
  .mu-sortcol { padding-left: 0; padding-top: 12px; }
  .mu-sortbar { margin-left: 0; }
  /* 窄屏胶囊会折行，这时才需要 6 的下外边距当行距（= flex-wrap 的 gap-1.5）。 */
  .mu-chip { margin-bottom: 6px; }
}
