/* ==================================================================
   sanjin的网站 · 首页
   布局：无缝拼图墙（背景/壁纸） + 顶部站标/搜索 + 底部播放器（默认收起）
   纯 CSS / 零第三方依赖
   ================================================================== */

:root {
  --g: 12px;                        /* 墙的列间距 / 外边距 */
  --ink: #f5f5f7;
  --dim: rgba(245, 245, 247, .58);
  --line: rgba(255, 255, 255, .12);
  --c1: #ff5e3a;
  --c2: #7b2ff7;
  --ph: none;
  --px: 0px;
  --py: 0px;
  --rx: 0deg;
  --ry: 0deg;
  --ease: cubic-bezier(.22, .61, .36, 1);
  --r-card: 26px;
  --r-tile: 14px;
  --top-h: 56px;
  --bot-h: 66px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

html, body { height: 100%; }

body {
  margin: 0;
  overflow: hidden;
  background: #07070a;
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
               "PingFang SC", "HarmonyOS Sans SC", "Segoe UI", "Microsoft YaHei", sans-serif;
  letter-spacing: .01em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

::selection { background: rgba(255, 255, 255, .22); }

button, input { font: inherit; color: inherit; }

/* ============================ 背景封面墙 ============================ */

.wall {
  position: fixed;
  left: -6vw; top: -6vh;
  width: 112vw; height: 112vh;
  z-index: 0;
  display: flex;
  gap: var(--g);
  padding: var(--g);
  transform: translate3d(var(--px), var(--py), 0);
  will-change: transform;
}

.wall__col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--g);
}

.tile {
  position: relative;
  flex: 0 0 auto;
  width: 100%;
  height: var(--th, 170px);
  padding: 0;
  border: 0;
  border-radius: var(--r-tile);
  overflow: hidden;
  cursor: pointer;
  text-align: left;
  background-color: var(--c1);
  background-image:
    linear-gradient(180deg, rgba(0, 0, 0, .02), rgba(0, 0, 0, .30)),
    var(--ph, none),
    linear-gradient(150deg, var(--c1), var(--c2));
  background-size: cover, cover, cover;
  background-position: center, center, center;
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-blend-mode: normal, luminosity, normal;
  filter: saturate(.72) brightness(.92) hue-rotate(var(--hue, 0deg));
  transition: transform .55s var(--ease), box-shadow .55s var(--ease), filter .55s var(--ease), opacity .45s var(--ease);
}

.tile::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .07);
  pointer-events: none;
}

.tile:hover,
.tile.is-live {
  filter: saturate(1.06) brightness(1.06) hue-rotate(var(--hue, 0deg));
  transform: scale(1.03);
  box-shadow: 0 26px 50px -16px rgba(0, 0, 0, .85);
  z-index: 2;
}

.tile.is-live {
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .5), 0 26px 50px -16px rgba(0, 0, 0, .85);
}

.tile.is-off { filter: saturate(.1) brightness(.5); }
.tile.is-off:hover { filter: saturate(.35) brightness(.68); }

.tile.is-dim { opacity: .2; }

.tile__idx {
  position: absolute;
  left: 8px; top: 7px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .05em;
  color: rgba(255, 255, 255, .72);
  text-shadow: 0 1px 7px rgba(0, 0, 0, .65);
  font-variant-numeric: tabular-nums;
}

.tile__mark {
  position: absolute;
  left: 10px; bottom: 9px;
  font-size: clamp(12px, calc(var(--th, 170px) * .135), 27px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: .005em;
  color: rgba(255, 255, 255, .78);
  text-shadow: 0 2px 12px rgba(0, 0, 0, .6);
  white-space: nowrap;
  opacity: .8;
  transition: opacity .45s var(--ease);
  pointer-events: none;
}

.tile:hover .tile__mark,
.tile.is-live .tile__mark { opacity: 0; }

.tile__label {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 26px 10px 8px;
  font-size: 11.5px;
  line-height: 1.3;
  color: #fff;
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, .8));
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .42s var(--ease), transform .42s var(--ease);
  pointer-events: none;
}

.tile:hover .tile__label,
.tile.is-live .tile__label { opacity: 1; transform: none; }

/* 音乐瓦片：曲名常显，读起来就像一张真唱片 */
.tile--mus .tile__label {
  opacity: .78;
  transform: none;
  font-weight: 500;
  letter-spacing: .01em;
}
.tile--mus:hover .tile__label,
.tile--mus.is-live .tile__label { opacity: 1; }

/* ============================== 压暗层 ============================== */

.veil {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(115% 85% at 50% 45%, rgba(6, 6, 9, .22) 0%, rgba(6, 6, 9, .42) 48%, rgba(5, 5, 8, .84) 100%),
    linear-gradient(180deg, rgba(5, 5, 8, .5) 0%, rgba(5, 5, 8, .3) 28%, rgba(5, 5, 8, .38) 68%, rgba(5, 5, 8, .88) 100%);
}

.veil::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* =========================== 顶部搜索栏 =========================== */

.topbar {
  position: fixed;
  left: 0; right: 0; top: 0;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  padding-top: calc(10px + env(safe-area-inset-top, 0px));
  background: linear-gradient(180deg, rgba(10, 10, 13, .82), rgba(10, 10, 13, 0));
}

.search {
  position: relative;
  flex: 1 1 auto;
  /* 关键：不加 min-width:0，flex 项的最小尺寸就是「内容的 min-content 宽度」，
     搜索框会死守 237px 不肯再缩，360px 以下的手机直接把它顶出屏幕右侧。 */
  min-width: 0;
  max-width: 460px;
  height: 36px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 6px 0 33px;
  border-radius: 999px;
  background: rgba(22, 22, 27, .6);
  border: 1px solid rgba(255, 255, 255, .1);
  backdrop-filter: blur(22px) saturate(1.4);
  -webkit-backdrop-filter: blur(22px) saturate(1.4);
  transition: background .3s var(--ease), border-color .3s var(--ease);
}

.search:focus-within {
  background: rgba(36, 36, 42, .78);
  border-color: rgba(255, 255, 255, .26);
}

.search__ico {
  position: absolute;
  left: 12px; top: 50%;
  width: 15px; height: 15px;
  transform: translateY(-50%);
  fill: none;
  stroke: rgba(245, 245, 247, .5);
  stroke-width: 1.6;
  stroke-linecap: round;
}

.search input {
  /* flex-basis 归零：input 自带约 138px 的固有宽度，用 auto 的话
     它会把自己的固有宽度算进外层 search 的 min-content，窄屏就缩不动了 */
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  border: 0;
  background: transparent;
  outline: none;
  font-size: 12.5px;
}

.search input::placeholder { color: rgba(245, 245, 247, .34); }
.search input::-webkit-search-cancel-button { display: none; }

.search button {
  flex: 0 0 auto;
  height: 26px;
  padding: 0 13px;
  border: 0;
  border-radius: 999px;
  background: #fff;
  color: #0b0b0e;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}

.search button:hover { opacity: .86; }
.search button:active { transform: scale(.95); }

/* 顶栏原来右上角那排「全部 / 运行中 / 已停用」的筛子按需求整体去掉了。
   去掉之后顶栏就剩「站标 + 音乐·入口 + 搜索」三段，
   桌面端让搜索靠右，左边和右边各有一块留白，比挤在中间更稳。 */

@media (min-width: 900px) {
  .topbar { gap: 16px; padding: 12px 26px; padding-top: calc(12px + env(safe-area-inset-top, 0px)); }
  .search { margin-left: auto; max-width: 420px; }
}

@media (min-width: 1280px) {
  .topbar { padding-left: 34px; padding-right: 34px; }
  .search { max-width: 460px; }
}

/* =========================== 中央玻璃卡片 =========================== */

.stage {
  position: fixed;
  left: 50%; top: 50%;
  z-index: 3;
  width: clamp(420px, 30vw, 520px);
  padding: 20px 22px 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  border-radius: var(--r-card);
  border: 1px solid rgba(255, 255, 255, .14);
  overflow: hidden;
  isolation: isolate;
  box-shadow:
    0 48px 92px -22px rgba(0, 0, 0, .88),
    0 0 0 1px rgba(0, 0, 0, .35),
    0 0 100px -34px var(--c1);
  transform: translate(-50%, -50%) perspective(1200px) rotateX(var(--rx)) rotateY(var(--ry));
  /* scale 用独立属性，跟上面那条 transform（含视差 rotateX/rotateY）互不干扰 */
  scale: 1;
  transition: box-shadow .7s var(--ease), opacity .4s var(--ease), scale .6s var(--ease), visibility .4s;
}

/* 默认不展示这张「单独一张图」的卡片。
   只有两种手势能让它浮出来（见 script.js 的 revealStage）：
     1) 点图片墙上任意一张；
     2) 在同一张上停留满 5 秒。
   打开首页时先看到的应该是一整面图片墙，而不是一张被单独放大的图。 */
.stage.is-hidden {
  opacity: 0;
  visibility: hidden;
  scale: .93;
  pointer-events: none;
}

.stage__art {
  position: absolute;
  inset: -20%;
  z-index: -2;
  background-image: var(--ph, none);
  background-size: cover;
  background-position: center;
  background-color: var(--c2);
  filter: blur(40px) saturate(1.12) brightness(.44);
  transform: scale(1.2);
}

.stage::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg,
    rgba(12, 12, 16, .24) 0%,
    rgba(9, 9, 12, .56) 46%,
    rgba(5, 5, 8, .95) 100%);
}

.stage__head { display: flex; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px 5px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  letter-spacing: .05em;
  color: rgba(245, 245, 247, .8);
  background: rgba(255, 255, 255, .09);
  border: 1px solid rgba(255, 255, 255, .1);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.pill__dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #30d158;
  box-shadow: 0 0 0 3px rgba(48, 209, 88, .18);
  animation: pulse 2.4s var(--ease) infinite;
}

.stage.is-off .pill__dot {
  background: #8e8e93;
  box-shadow: 0 0 0 3px rgba(142, 142, 147, .16);
  animation: none;
}

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

.stage__cover {
  position: relative;
  display: block;
  width: 86%;
  margin: 0 auto;
  aspect-ratio: 1 / 0.84;
  padding: 0;
  border: 0;
  border-radius: 16px;
  overflow: hidden;
  cursor: pointer;
  background-color: var(--c1);
  background-image:
    linear-gradient(180deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, .34)),
    var(--ph, none),
    linear-gradient(150deg, var(--c1), var(--c2));
  background-size: cover, cover, cover;
  /* 这张卡是横向的（1 / 0.84），照片是竖构图 —— 同样往上取景才留得住人 */
  background-position: center 30%, center 30%, center;
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-blend-mode: normal, normal, normal;
  box-shadow: 0 18px 42px -16px rgba(0, 0, 0, .8), inset 0 0 0 1px rgba(255, 255, 255, .1);
  transition: transform .55s var(--ease);
}

.stage__cover:hover { transform: scale(1.012); }

.stage__mark {
  position: absolute;
  left: 16px; bottom: 12px;
  font-size: clamp(22px, 3.4vw, 34px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.035em;
  color: #fff;
  opacity: .93;
  text-shadow: 0 4px 22px rgba(0, 0, 0, .55);
  transition: opacity .45s var(--ease);
}

.stage__glow {
  position: absolute;
  inset: 0;
  background: radial-gradient(62% 56% at 50% 44%, rgba(255, 255, 255, .16), transparent 72%);
  opacity: 0;
  transition: opacity .55s var(--ease);
}

.stage__cover:hover .stage__glow { opacity: 1; }

.stage__play {
  position: absolute;
  left: 50%; top: 50%;
  width: 68px; height: 68px;
  display: grid;
  place-items: center;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 8px 24px rgba(0, 0, 0, .6));
  transition: transform .48s var(--ease), opacity .48s var(--ease);
}

.stage__play svg { width: 48px; height: 48px; fill: #fff; }

.stage__cover:hover .stage__play { transform: translate(-50%, -50%) scale(1.1); }

.stage__hint {
  position: absolute;
  left: 50%; bottom: 13px;
  transform: translate(-50%, 8px);
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 11.5px;
  letter-spacing: .04em;
  color: #fff;
  background: rgba(0, 0, 0, .45);
  border: 1px solid rgba(255, 255, 255, .16);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  white-space: nowrap;
  transition: opacity .42s var(--ease), transform .42s var(--ease);
  pointer-events: none;
}

.stage__cover:hover .stage__hint { opacity: 1; transform: translate(-50%, 0); }
.stage__cover:hover .stage__mark { opacity: 0; }

.stage__disc {
  position: absolute;
  right: 14px; bottom: 13px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, rgba(255, 255, 255, .92), rgba(255, 255, 255, .12) 42%, rgba(255, 255, 255, .92));
  -webkit-mask: radial-gradient(circle, transparent 0 4px, #000 4px);
  mask: radial-gradient(circle, transparent 0 4px, #000 4px);
  opacity: .5;
  animation: spin 9s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

.stage__title {
  margin: 0;
  font-size: clamp(25px, 4vw, 37px);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -.028em;
  color: #fff;
  text-shadow: 0 3px 26px rgba(0, 0, 0, .5);
}

.stage__sub {
  margin: 7px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  letter-spacing: .015em;
  color: rgba(245, 245, 247, .62);
}

.stage__acts {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 2px;
}

.ico {
  width: 36px; height: 36px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: rgba(245, 245, 247, .74);
  cursor: pointer;
  transition: background .28s var(--ease), color .28s var(--ease), transform .28s var(--ease);
}

.ico svg {
  width: 19px; height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.55;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.ico:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.ico:active { transform: scale(.92); }

.stage__spacer { flex: 1; }

.stage__count {
  font-size: 11.5px;
  letter-spacing: .1em;
  color: rgba(245, 245, 247, .42);
  font-variant-numeric: tabular-nums;
}

/* ============================ 播放器控制条 ============================ */

.player {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 7;
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: var(--bot-h);
  padding: 11px 16px calc(11px + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(180deg, rgba(14, 14, 18, .58), rgba(9, 9, 12, .9));
  border-top: 1px solid rgba(255, 255, 255, .08);
  backdrop-filter: blur(26px) saturate(1.5);
  -webkit-backdrop-filter: blur(26px) saturate(1.5);
}

/* 左：当前曲目 */
.now {
  flex: 0 1 230px;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 10px;
}

.now__art {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  border-radius: 11px;
  background-color: rgba(255, 255, 255, .08);
  background-image: linear-gradient(150deg, #ff5e3a, #7b2ff7);
  background-size: cover;
  background-position: center;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14);
  display: grid;
  place-items: center;
}

.now__art svg {
  width: 19px; height: 19px;
  fill: none;
  stroke: rgba(255, 255, 255, .8);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.now__art.has-cover svg { display: none; }

.now__meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.3;
}

.now__meta b {
  font-size: 12.5px;
  font-weight: 600;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.now__meta i {
  font-style: normal;
  font-size: 11px;
  color: rgba(245, 245, 247, .5);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 中：播放控制 */
.pctrl {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 2px;
}

.pbtn {
  width: 36px; height: 36px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: rgba(245, 245, 247, .74);
  cursor: pointer;
  position: relative;
  transition: background .28s var(--ease), color .28s var(--ease), transform .28s var(--ease);
}

.pbtn svg {
  width: 19px; height: 19px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pbtn:hover { background: rgba(255, 255, 255, .12); color: #fff; }
.pbtn:active { transform: scale(.9); }

.pbtn--main {
  width: 42px; height: 42px;
  background: #fff;
  color: #0b0b0e;
  margin: 0 4px;
}

.pbtn--main:hover { background: #fff; color: #0b0b0e; opacity: .88; }
.pbtn--main svg { width: 21px; height: 21px; stroke-width: 1.9; }
.pbtn--main .ic-play { fill: #0b0b0e; stroke: none; margin-left: 2px; }
.pbtn--main .ic-pause { display: none; }

.player.is-playing .pbtn--main .ic-play { display: none; }
.player.is-playing .pbtn--main .ic-pause { display: block; }

.pbtn.is-on { color: #fff; background: rgba(255, 255, 255, .14); }

.badge {
  position: absolute;
  right: 3px; bottom: 3px;
  font-style: normal;
  font-size: 8.5px;
  font-weight: 700;
  line-height: 1;
  padding: 1px 3px;
  border-radius: 4px;
  background: #fff;
  color: #0b0b0e;
  display: none;
}

.pbtn.is-badge .badge { display: block; }

/* 中：进度 */
.seek {
  flex: 1 1 auto;
  min-width: 80px;
  display: flex;
  align-items: center;
  gap: 9px;
}

.tm {
  flex: 0 0 auto;
  font-size: 11.5px;
  color: rgba(245, 245, 247, .55);
  font-variant-numeric: tabular-nums;
  min-width: 34px;
  text-align: center;
}

.range {
  -webkit-appearance: none;
  appearance: none;
  flex: 1 1 auto;
  min-width: 0;
  height: 16px;
  background: transparent;
  cursor: pointer;
  outline: none;
}

.range::-webkit-slider-runnable-track {
  height: 3px;
  border-radius: 999px;
  background: linear-gradient(90deg, #fff 0 var(--p, 0%), rgba(255, 255, 255, .2) var(--p, 0%) 100%);
}

.range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 11px; height: 11px;
  margin-top: -4px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 5px rgba(0, 0, 0, .55);
  transition: transform .25s var(--ease);
}

.range:hover::-webkit-slider-thumb { transform: scale(1.2); }

.range:disabled { opacity: .35; pointer-events: none; }

.range::-moz-range-track {
  height: 3px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .2);
}

.range::-moz-range-progress {
  height: 3px;
  border-radius: 999px;
  background: #fff;
}

.range::-moz-range-thumb {
  width: 11px; height: 11px;
  border: 0;
  border-radius: 50%;
  background: #fff;
}

/* 右：随机 / 循环 / 音量 / 列表 */
.pright {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 2px;
}

.vol {
  display: flex;
  align-items: center;
  gap: 2px;
}

.range--v {
  flex: 0 0 74px;
  width: 74px;
}

/* ============================ 播放列表抽屉 ============================ */

.scrim {
  position: fixed;
  inset: 0;
  z-index: 8;
  background: rgba(0, 0, 0, .42);
  opacity: 0;
  pointer-events: none;
  transition: opacity .38s var(--ease);
}

.scrim.is-open { opacity: 1; pointer-events: auto; }

.drawer {
  position: fixed;
  left: 50%;
  bottom: calc(var(--bot-h) + 12px + env(safe-area-inset-bottom, 0px));
  z-index: 9;
  width: min(560px, calc(100vw - 32px));
  max-height: min(58vh, 460px);
  display: flex;
  flex-direction: column;
  border-radius: 22px;
  border: 1px solid rgba(255, 255, 255, .13);
  background: rgba(16, 16, 20, .82);
  backdrop-filter: blur(30px) saturate(1.6);
  -webkit-backdrop-filter: blur(30px) saturate(1.6);
  box-shadow: 0 40px 80px -24px rgba(0, 0, 0, .9);
  transform: translate(-50%, 18px) scale(.98);
  opacity: 0;
  pointer-events: none;
  transition: opacity .34s var(--ease), transform .34s var(--ease);
}

.drawer.is-open {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
  pointer-events: auto;
}

.drawer__head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 13px 11px 18px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.drawer__head b { font-size: 13.5px; font-weight: 600; }

.drawer__count {
  font-size: 11.5px;
  color: rgba(245, 245, 247, .48);
  font-variant-numeric: tabular-nums;
}

.drawer__head .pbtn { margin-left: auto; }

.drawer__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 6px;
}

/* 注意：一旦写了 scrollbar-width / scrollbar-color，Chrome 会弃用下面的
   ::-webkit-scrollbar 自定义样式，改用系统滚动条（在深色毛玻璃上很扎眼）。
   所以这里只用 webkit 伪元素，不写标准属性。 */
.drawer__body::-webkit-scrollbar { width: 9px; }
.drawer__body::-webkit-scrollbar-track { background: transparent; }
.drawer__body::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .16);
  border: 3px solid transparent;
  background-clip: padding-box;
  border-radius: 999px;
}
.drawer__body::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, .3); background-clip: padding-box; }

.row {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 7px 10px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .25s var(--ease);
}

.row:hover { background: rgba(255, 255, 255, .08); }

.row.is-cur { background: rgba(255, 255, 255, .13); }

.row__art {
  flex: 0 0 auto;
  width: 38px; height: 38px;
  border-radius: 9px;
  background-color: rgba(255, 255, 255, .08);
  background-image: linear-gradient(150deg, #ff5e3a, #7b2ff7);
  background-size: cover;
  background-position: center;
  display: grid;
  place-items: center;
}

.row__art svg {
  width: 17px; height: 17px;
  fill: none;
  stroke: rgba(255, 255, 255, .72);
  stroke-width: 1.5;
  stroke-linecap: round;
}

.row__art.has-cover svg { display: none; }

.row__txt {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.32;
}

.row__txt b {
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.row.is-cur .row__txt b { font-weight: 600; }

.row__txt i {
  font-style: normal;
  font-size: 11px;
  color: rgba(245, 245, 247, .48);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.row__no {
  flex: 0 0 auto;
  font-size: 11px;
  color: rgba(245, 245, 247, .4);
  font-variant-numeric: tabular-nums;
  min-width: 20px;
  text-align: right;
}

.row.is-cur .row__no { color: rgba(245, 245, 247, .8); }

.drawer__foot {
  flex: 0 0 auto;
  padding: 11px 18px 13px;
  border-top: 1px solid rgba(255, 255, 255, .08);
  font-size: 11.5px;
  line-height: 1.6;
  color: rgba(245, 245, 247, .5);
}

.drawer__foot code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  padding: 1px 5px;
  border-radius: 5px;
  background: rgba(255, 255, 255, .1);
  color: rgba(245, 245, 247, .82);
}

/* 空态 */
.empty {
  padding: 26px 20px 30px;
  text-align: center;
  color: rgba(245, 245, 247, .5);
  font-size: 12px;
  line-height: 1.9;
}

.empty b {
  display: block;
  margin-bottom: 6px;
  font-size: 13.5px;
  font-weight: 600;
  color: rgba(245, 245, 247, .84);
}

/* ============================== 提示条 ============================== */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--bot-h) + 18px + env(safe-area-inset-bottom, 0px));
  z-index: 20;
  padding: 9px 17px;
  border-radius: 999px;
  background: rgba(20, 20, 24, .9);
  border: 1px solid rgba(255, 255, 255, .12);
  color: #fff;
  font-size: 12.5px;
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  opacity: 0;
  transform: translate(-50%, 10px);
  pointer-events: none;
  transition: opacity .32s var(--ease), transform .32s var(--ease);
}

.toast.is-show { opacity: 1; transform: translate(-50%, 0); }

/* ============================== 响应式 ============================== */

@media (max-width: 1100px) {
  .range--v { flex-basis: 56px; width: 56px; }
  .now { flex-basis: 180px; }
}

@media (max-width: 900px) {
  .stage { transform: translate(-50%, -50%); }
  .vol { display: none; }
}

@media (max-width: 820px) {
  :root { --g: 9px; --bot-h: 96px; }
  .stage {
    width: min(430px, calc(100vw - 28px));
    padding: 16px 16px 14px;
    border-radius: 22px;
  }
  .topbar { gap: 8px; padding-left: 12px; padding-right: 12px; }
  .stage__count { display: none; }

  /* 播放器折成两行：上行 曲目+按钮，下行 进度 */
  .player { flex-wrap: wrap; gap: 6px 10px; padding-left: 12px; padding-right: 12px; }
  .now { flex: 1 1 auto; order: 1; }
  .now__art { width: 34px; height: 34px; border-radius: 9px; }
  .pctrl { order: 2; }
  .pright { order: 3; }
  .seek { order: 4; flex: 1 0 100%; }
  .range--v { display: none; }
  .pbtn { width: 34px; height: 34px; }
  .pbtn--main { width: 40px; height: 40px; }
  .tm { min-width: 30px; font-size: 11px; }
  .drawer { bottom: calc(var(--bot-h) + 8px + env(safe-area-inset-bottom, 0px)); max-height: 56vh; }
}

@media (max-width: 430px) {
  .stage__acts .ico[data-act="prev"],
  .stage__acts .ico[data-act="next"] { display: none; }
  .stage__mark { left: 13px; bottom: 10px; }
  .stage__hint { display: none; }
  .pright .pbtn[data-p="shuffle"] { display: none; }
}

@media (max-width: 390px) {
  .now__meta i { display: none; }
}

/* 顶栏三段（站标 / 音乐·入口 / 搜索）在手机竖屏里挤一行：
   一律只压缩间距和内边距，不隐藏功能 —— 320px 的老机器也要能完整看到「播放」按钮 */
@media (max-width: 480px) {
  .topbar { gap: 7px; padding-left: 10px; padding-right: 10px; }
  .seg { padding: 2px; }
  .seg__btn { height: 28px; padding: 0 10px; font-size: 11.5px; }
  .search { height: 34px; padding: 0 4px 0 29px; gap: 6px; }
  .search__ico { left: 10px; width: 14px; height: 14px; }
  .search input { font-size: 12px; }
  .search button { height: 24px; padding: 0 10px; font-size: 11px; }
}

@media (max-width: 375px) {
  .topbar { gap: 6px; }
  .seg__btn { padding: 0 8px; font-size: 11px; }
  .search { padding-left: 27px; }
  .search button { padding: 0 9px; }
}

/* 横屏手机 / 矮视口：顶栏本身不用动，但别让 stage 卡片被压扁 */
@media (max-height: 460px) and (max-width: 900px) {
  .topbar { padding-top: calc(6px + env(safe-area-inset-top, 0px)); padding-bottom: 6px; }
}

@media (max-height: 720px) {
  .stage__cover { aspect-ratio: 1 / 0.6; }
  .stage__title { font-size: 24px; }
  .stage { gap: 11px; padding: 15px 16px 13px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
  /* 例外：悬停 5 秒的进度条是「还有多久会放大」的功能提示，不是装饰动画，
     所以即便系统关掉了动画，它也要照常走满 5 秒。 */
  .tile:hover .tile__hold { animation-duration: 5s !important; }
  .wall { transform: none !important; }
  .stage { transform: translate(-50%, -50%) !important; }
}

/* ==================================================================
   追加：模式切换 / 悬停 5 秒进度条 / 单图放大视图
   ================================================================== */

/* ---------------------- 顶部 音乐 / 入口 切换 ---------------------- */

.seg {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  gap: 2px;
  padding: 3px;
  border-radius: 999px;
  background: rgba(22, 22, 27, .6);
  border: 1px solid rgba(255, 255, 255, .1);
  backdrop-filter: blur(22px) saturate(1.4);
  -webkit-backdrop-filter: blur(22px) saturate(1.4);
}

.seg__btn {
  height: 30px;
  padding: 0 14px;
  display: flex;
  align-items: center;
  gap: 5px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: rgba(245, 245, 247, .66);
  font-size: 12px;
  cursor: pointer;
  transition: background .28s var(--ease), color .28s var(--ease);
}

.seg__btn:hover { color: #fff; }

.seg__btn.is-on {
  background: #fff;
  color: #0b0b0e;
  font-weight: 600;
}

/* 「音乐」后面那个曲目数徽标（.seg__btn span）按需求去掉了 ——
   顶栏只留「音乐 / 入口」两个干净的字，曲目总数看歌单抽屉页脚。 */

/* ------------------- 悬停 5 秒：顶部进度条 ------------------- */

.tile__hold {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 3px;
  background: #fff;
  opacity: 0;
  transform: scaleX(0);
  transform-origin: left center;
  pointer-events: none;
  z-index: 3;
}

.tile:hover .tile__hold {
  opacity: .92;
  animation: holdfill 5s linear forwards;
}

@keyframes holdfill {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

/* ----------------------- 单图放大视图 ----------------------- */

.solo {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 22px 0 calc(var(--bot-h) + 78px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .42s var(--ease);
}

.solo.is-open { opacity: 1; pointer-events: auto; }

.solo__bg {
  position: absolute;
  inset: -12%;
  background-image: var(--solo-ph, none);
  background-size: cover;
  background-position: center;
  background-color: #0a0a0d;
  filter: blur(64px) saturate(1.25) brightness(.32);
  transform: scale(1.18);
}

.solo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(72% 62% at 50% 44%, rgba(6, 6, 9, .2) 0%, rgba(4, 4, 6, .88) 100%);
}

.solo__frame {
  position: relative;
  z-index: 2;
  height: min(54vh, 96vw);
  aspect-ratio: 1 / 1.12;
  border-radius: 22px;
  overflow: hidden;
  cursor: zoom-out;
  box-shadow: 0 54px 110px -34px rgba(0, 0, 0, .95), 0 0 0 1px rgba(255, 255, 255, .15);
  opacity: 0;
  transform: scale(.88);
  transition: opacity .42s var(--ease), transform .5s var(--ease);
}

.solo.is-open .solo__frame { opacity: 1; transform: none; }

.solo__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.solo__info {
  position: relative;
  z-index: 2;
  margin-top: 22px;
  padding: 0 26px;
  text-align: center;
}

.solo__title {
  margin: 0;
  font-size: clamp(21px, 3.2vw, 33px);
  font-weight: 700;
  letter-spacing: -.026em;
  line-height: 1.15;
  color: #fff;
  text-shadow: 0 3px 24px rgba(0, 0, 0, .55);
}

.solo__sub {
  margin: 8px 0 0;
  font-size: 12.5px;
  letter-spacing: .015em;
  color: rgba(245, 245, 247, .6);
}

.solo__bar {
  position: relative;
  z-index: 2;
  margin-top: 20px;
  display: flex;
  align-items: center;
  gap: 9px;
}

.solo__main {
  height: 42px;
  padding: 0 28px;
  border: 0;
  border-radius: 999px;
  background: #fff;
  color: #0b0b0e;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity .25s var(--ease), transform .25s var(--ease);
}

.solo__main:hover { opacity: .88; }
.solo__main:active { transform: scale(.96); }

.solo .pbtn {
  width: 42px;
  height: 42px;
  background: rgba(255, 255, 255, .1);
  border: 1px solid rgba(255, 255, 255, .12);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

.solo .pbtn:hover { background: rgba(255, 255, 255, .2); }

.solo__tip {
  position: absolute;
  left: 0; right: 0;
  bottom: calc(var(--bot-h) + 22px + env(safe-area-inset-bottom, 0px));
  z-index: 2;
  text-align: center;
  font-size: 11.5px;
  color: rgba(245, 245, 247, .38);
}

/* -------------------- 中央卡片播放/暂停图标 -------------------- */

.stage__play .ic-pause {
  width: 42px;
  height: 42px;
  fill: none;
  stroke: #fff;
  stroke-width: 2.4;
  stroke-linecap: round;
  display: none;
}

.stage.is-playing .stage__play .ic-play { display: none; }
.stage.is-playing .stage__play .ic-pause { display: block; }

/* 音乐模式下不显示角标文字（右侧那个小唱片） */
.stage.is-mus .stage__disc { display: none; }

/* ----------------------- 歌单内筛选框 ----------------------- */

.drawer__head .pbtn { margin-left: 0; }

.drawer__filter {
  flex: 0 1 140px;
  min-width: 74px;
  height: 28px;
  margin-left: auto;
  padding: 0 11px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .1);
  background: rgba(255, 255, 255, .06);
  color: #fff;
  font-size: 12px;
  outline: none;
  transition: background .28s var(--ease), border-color .28s var(--ease);
}

.drawer__filter::placeholder { color: rgba(245, 245, 247, .32); }
.drawer__filter:focus { background: rgba(255, 255, 255, .13); border-color: rgba(255, 255, 255, .24); }
.drawer__filter::-webkit-search-cancel-button { display: none; }

/* ------------------------- 响应式补充 ------------------------- */

@media (max-width: 900px) {
  .solo { padding-bottom: calc(var(--bot-h) + 70px); }
  .solo__tip { display: none; }
}

@media (max-width: 820px) {
  .seg__btn { padding: 0 11px; font-size: 11.5px; }
  .drawer__filter { flex-basis: 96px; }
  .solo__bar { gap: 7px; }
  .solo__main { height: 40px; padding: 0 22px; }
  .solo .pbtn { width: 40px; height: 40px; }
}

@media (max-width: 430px) {
  .drawer__filter { display: none; }
}

/* ==================================================================
   追加 2：色相跟随（同一张底图，每首歌一个色相）/ 筛选条显隐
   ================================================================== */

/* 中央卡片封面、单图放大视图 —— 与瓦片用同一个 --hue，视觉才连得上 */
.stage__cover { filter: hue-rotate(var(--hue, 0deg)); }

.solo__img { filter: hue-rotate(var(--hue, 0deg)); }

/* 覆盖上面的 .solo__bg，把色相也带上 */
.solo__bg {
  filter: blur(64px) saturate(1.25) brightness(.32) hue-rotate(var(--hue, 0deg));
}

/* 悬停计时中：右下角补一个极轻的呼吸，提示"马上会放大" */
.tile:hover .tile__hold { box-shadow: 0 0 12px rgba(255, 255, 255, .55); }

/* ==================================================================
   追加 3：底部备案号
   z-index 5 —— 压在图片墙/中央卡片之上，躲在播放器(7)、抽屉(9)之下
   ================================================================== */

.beian {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(var(--bot-h) + 14px + env(safe-area-inset-bottom, 0px));
  z-index: 5;
  display: flex;
  justify-content: center;
  pointer-events: none;
}

.beian a {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 13px;
  border-radius: 999px;
  font-size: 11.5px;
  letter-spacing: .045em;
  color: rgba(245, 245, 247, .46);
  text-decoration: none;
  background: rgba(22, 22, 27, .42);
  border: 1px solid rgba(255, 255, 255, .07);
  backdrop-filter: blur(18px) saturate(1.3);
  -webkit-backdrop-filter: blur(18px) saturate(1.3);
  transition: color .3s var(--ease), background .3s var(--ease),
              border-color .3s var(--ease), transform .2s var(--ease);
}

.beian a:hover {
  color: rgba(245, 245, 247, .96);
  background: rgba(34, 34, 41, .62);
  border-color: rgba(255, 255, 255, .16);
}

.beian a:active { transform: scale(.97); }

.beian svg {
  width: 12px; height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .82;
}

@media (max-width: 430px) {
  .beian { bottom: calc(var(--bot-h) + 10px + env(safe-area-inset-bottom, 0px)); }
  .beian a { padding: 4px 11px; font-size: 11px; gap: 5px; }
  .beian svg { width: 11px; height: 11px; }
}

@media (max-height: 720px) {
  .beian { bottom: calc(var(--bot-h) + 8px + env(safe-area-inset-bottom, 0px)); }
}

/* ==================================================================
   追加 4：壁纸化改版
     · 背景墙改成「无缝拼图」——行内按画幅比分配宽度，行行紧贴、没有缝，
       每张瓦片的形状（横/方/竖）都不一样
     · 点选效果改成「选中的那张按比例原地放大」，不再有浮在中间的玻璃卡
     · 播放器默认收起，开始播放时自动滑出，可以随时再收回去
     · 闲置几秒把顶栏/备案号淡掉，让首页更像一张壁纸
   ================================================================== */

/* ---------------------- 1. 无缝拼图墙 ---------------------- */

.wall {
  left: -3vw; top: -3vh;
  width: 106vw; height: 106vh;
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
  overflow: hidden;
}

.wall__row {
  display: flex;
  flex: 0 0 auto;
  width: 100%;
}

/* 分页容器：每页都是「一整面墙」。
   之前 .wall 直接放行，现在行要分到不同的页里 —— 用绝对定位把每页盖在同一个
   位置，靠 opacity 交叉淡入淡出，翻页时像壁纸幻灯一样换一整面。
   注意：非当前页必须 pointer-events:none，否则透明的那几页还会抢走鼠标。 */
.wall__pages {
  position: absolute;
  inset: 0;
}

.wall__page {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transition: opacity .78s var(--ease);
}

.wall__page.is-on {
  opacity: 1;
  pointer-events: auto;
}

/* flex-grow = 该张的画幅比 → 宽度按比例分完整行，天然不留缝 */
.wall__row .tile {
  flex: var(--ar, 1) 1 0;
  width: auto;
  height: 100%;
  min-width: 0;
  border-radius: 0;
}

/* 拼图里不要那圈内描边 */
.wall__row .tile::after { box-shadow: none; }

/* 壁纸观感 —— 这一段要覆盖基础 .tile 那套「照片只取明度、再拿底色去染」的画法。
   墙底图现在是真实照片（covers/01…58.jpg），再走 luminosity 就等于把照片本身
   染成一片灰蓝单色，白换了。所以改成全彩：
     · blend 全 normal —— 照片原色直出，不再跟底色做明度混合；
     · 靠 filter 把它压到「壁纸」亮度 —— 压暗 + 微降饱和 + 微提对比，
       照片看得清、颜色也还在，但不会亮过上面的顶栏和玻璃卡；
     · 瓦片自带的渐变要压得很轻：它是一行一层，铺满屏就是几十条横向暗带；
       整体压暗交给上面那层 .veil（全屏渐变），行间才不会出现「横条纹」。 */
.wall__row .tile {
  filter: saturate(.96) brightness(.92) contrast(1.05);
  background-image:
    linear-gradient(180deg, rgba(0, 0, 0, .05) 0%, rgba(0, 0, 0, 0) 42%, rgba(0, 0, 0, .14) 100%),
    var(--ph, none),
    linear-gradient(150deg,
      color-mix(in srgb, var(--c1, #3a4048) 22%, #2b2f37),
      color-mix(in srgb, var(--c2, #14171c) 26%, #0b0d10));
  background-size: cover, cover, cover;
  /* 取景位置由 script.js 按格子画幅比给：比源图还扁的横条格一律往上取，
     人像照片才不会只剩半张脸（竖向格子仍居中） */
  background-position: center var(--ppy, center), center var(--ppy, center), center;
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-blend-mode: normal, normal, normal;
}

/* 悬停 / 正在播放 —— 统一给一点点提亮（写在最后，盖过上面的基础值） */
.wall__row .tile:hover,
.wall__row .tile.is-live {
  filter: saturate(1.04) brightness(1.00) contrast(1.04);
}

/* 选中放大那一张：比悬停再提一档，暗底上才立得出来（压暗层已经把它衬出来了） */
.wall__row .tile.is-zoom {
  filter: saturate(1.06) brightness(1.12) contrast(1.03);
}

/* 停用的入口要看得出来是灰的 —— 基础 .tile.is-off 优先级不够，会被上面那条盖掉 */
.wall__row .tile.is-off {
  filter: saturate(.10) brightness(.40);
}
.wall__row .tile.is-off:hover {
  filter: saturate(.45) brightness(.64);
}

/* 默认不在瓦片上留字，鼠标扫过才报名字 */
.wall__row .tile .tile__label { opacity: 0; transform: translateY(6px); }
.wall__row .tile:hover .tile__label,
.wall__row .tile.is-zoom .tile__label { opacity: 1; transform: none; }

/* 「正在播放」只留一圈很淡的光，别抢戏 */
.tile.is-live {
  transform: none;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .38),
              0 0 34px -6px rgba(255, 255, 255, .18);
}

/* 压暗层：放大某张时把其余部分暗下去（同层里 z-index 低于被放大的那张） */
.wall__dim {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: rgba(4, 4, 7, .58);
  opacity: 0;
  pointer-events: none;
  transition: opacity .45s var(--ease);
}

.wall.is-focus .wall__dim { opacity: 1; }

/* 影子 —— 被选中的那张飞走后，原来的格位就露出一个洞，
   整面拼图会缺一块。所以在这一格原位补一张「用同一套画法画出来的替身」，
   等它飞回来盖住之后再撤掉（时间差由 JS 的 FLY_MS 控制）。
   它是 .wall 的子节点，所以跟着墙一起做视差位移，不会跟瓦片对不上。 */
.wall__ghost {
  position: absolute;
  z-index: 1;
  border-radius: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity .35s var(--ease);
}

.wall__ghost.is-on { opacity: 1; }

/* ---------------------- 2. 选中：等比放大 + 飞到屏幕正中 ---------------------- */

/* --zk 放大倍数 / --zx --zy 把这张的中心平移到视口中心，都由 JS 现算（见 zoomTile）。
   缩放是绕自身中心做的，所以中心点原地不动 ——
   只要把中心平移到 (vw/2, vh/2)，「变大」和「移到中间」就同时完成了，
   而且整面墙不动、没有另开一层，看着就是「同一个平面上的放大」。
   放大倍数不用死值，JS 会按「放大后整张仍留在视口内」反推一个上限。 */
.tile.is-zoom {
  z-index: 6;
  transform: translate(var(--zx, 0px), var(--zy, 0px)) scale(var(--zk, 1.9));
  border-radius: 9px;
  box-shadow: 0 48px 100px -22px rgba(0, 0, 0, .92),
              0 0 0 1px rgba(255, 255, 255, .16);
  transition: transform .52s cubic-bezier(.16, 1, .3, 1),
              box-shadow .5s var(--ease), filter .45s var(--ease);
}
/* （放大时的 filter 与悬停共用一条，写在「追加 4」的拼图段里，避免两处各写一半） */

/* 放大后底部那行：▶ + 歌名。
   它长在瓦片里，所以宽高和反向缩放都得跟着 --zk 走，
   视觉上才是正常字号、正好铺满放大后的那一张。 */
.tile__zoom {
  position: absolute;
  left: calc((1 - var(--zk, 1.9)) / 2 * 100%);
  bottom: 0;
  width: calc(var(--zk, 1.9) * 100%);
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 14px 16px 13px;
  transform: scale(var(--zi, .526));
  transform-origin: bottom center;
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, .74));
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .3s var(--ease) .16s;
}

.tile.is-zoom .tile__zoom { opacity: 1; visibility: visible; pointer-events: auto; }

.tile__zbtn {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  color: #0b0b0e;
  background: rgba(255, 255, 255, .94);
  box-shadow: 0 10px 24px -8px rgba(0, 0, 0, .7);
  transition: transform .28s var(--ease), background .28s var(--ease);
}

.tile__zbtn:hover { transform: scale(1.07); background: #fff; }
.tile__zbtn:active { transform: scale(.94); }
.tile__zbtn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.tile--mus .tile__zbtn svg { fill: currentColor; stroke: none; }

.tile__zoom b {
  font-size: 15.5px;
  font-weight: 700;
  letter-spacing: -.012em;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tile__zoom i {
  min-width: 0;
  font-size: 12px;
  font-style: normal;
  color: rgba(255, 255, 255, .6);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------------------- 3. 播放器：默认收起 ---------------------- */

:root { --dock: var(--bot-h); }

body:not(.player-open) { --dock: 0px; }

.player {
  transform: translateY(calc(100% + 30px));
  opacity: 0;
  pointer-events: none;
  transition: transform .52s var(--ease), opacity .42s var(--ease);
}

.player.is-open { transform: none; opacity: 1; pointer-events: auto; }

/* 底部留白：播放器收起时，备案号 / 歌单贴到底 */
.beian { bottom: calc(var(--dock) + 14px + env(safe-area-inset-bottom, 0px)); }
.drawer { bottom: calc(var(--dock) + 12px + env(safe-area-inset-bottom, 0px)); }

@media (max-width: 430px) {
  .beian { bottom: calc(var(--dock) + 10px + env(safe-area-inset-bottom, 0px)); }
}
@media (max-height: 720px) {
  .beian { bottom: calc(var(--dock) + 8px + env(safe-area-inset-bottom, 0px)); }
}

/* ---------------------- 4. 右下角小圆钮 ---------------------- */

.dock {
  position: fixed;
  right: 18px;
  bottom: calc(var(--dock) + 18px + env(safe-area-inset-bottom, 0px));
  z-index: 8;
  width: 46px; height: 46px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 50%;
  cursor: pointer;
  color: rgba(245, 245, 247, .92);
  background: rgba(20, 20, 25, .5);
  box-shadow: 0 16px 34px -14px rgba(0, 0, 0, .85);
  backdrop-filter: blur(20px) saturate(1.4);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  transition: transform .3s var(--ease), bottom .52s var(--ease),
              opacity .45s var(--ease), background .3s var(--ease);
}

.dock:hover { background: rgba(40, 40, 48, .7); transform: scale(1.06); }
.dock:active { transform: scale(.93); }

.dock__ico {
  width: 21px; height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.dock__eq { display: none; align-items: flex-end; gap: 3px; height: 17px; }
.dock.is-on .dock__ico { display: none; }
.dock.is-on .dock__eq { display: flex; }

.dock__eq b {
  width: 3px;
  height: 7px;
  border-radius: 2px;
  background: #fff;
  transform-origin: bottom center;
  animation: eq .95s var(--ease) infinite;
}

.dock__eq b:nth-child(2) { animation-delay: .17s; height: 13px; }
.dock__eq b:nth-child(3) { animation-delay: .33s; height: 9px; }

@keyframes eq {
  0%, 100% { transform: scaleY(.35); opacity: .7; }
  50% { transform: scaleY(1); opacity: 1; }
}

body.player-open .dock {
  opacity: 0;
  pointer-events: none;
  transform: scale(.86);
}

/* ---------------------- 5. 闲置 → 淡出顶栏，更像壁纸 ---------------------- */

.topbar { transition: opacity .5s var(--ease), transform .55s var(--ease); }
.beian { transition: opacity .5s var(--ease), bottom .52s var(--ease); }
.dock { transition: opacity .45s var(--ease), transform .3s var(--ease), bottom .52s var(--ease), background .3s var(--ease); }

body.is-idle .topbar {
  opacity: 0;
  transform: translateY(-124%);
  pointer-events: none;
}

body.is-idle .beian { opacity: 0; }
body.is-idle .dock { opacity: .34; }
body.is-idle .dock:hover { opacity: 1; }

/* ---------------------- 6. 收起按钮 ---------------------- */

.pbtn--fold svg { width: 20px; height: 20px; }

@media (max-width: 900px) {
  .pbtn--fold { order: 9; }
}

/* ==================================================================
   追加 6：扁平化站标（个人博客风）
   —— 纸白方标 + 墨色 S，纯色块、无渐变无高光。同一份图形也是 favicon。
   ================================================================== */

.brand {
  flex: 0 0 auto;                 /* 不参与搜索框那种伸缩 */
  display: inline-flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  text-decoration: none;
  color: var(--ink);
  -webkit-tap-highlight-color: transparent;
}

.brand__mark {
  flex: 0 0 auto;
  display: block;
  width: 26px;
  height: 26px;
  border-radius: 6px;             /* 跟 SVG 里的 rx=15/64 对齐（15/64×26 ≈ 6） */
  box-shadow: 0 2px 9px -4px rgba(0, 0, 0, .7);
  transition: transform .25s var(--ease);
}
.brand:hover .brand__mark { transform: scale(1.07); }
.brand:active .brand__mark { transform: scale(.96); }

.brand__name {
  font-size: 14px;
  font-weight: 650;
  letter-spacing: .1px;
  white-space: nowrap;
  color: rgba(245, 245, 247, .94);
  transition: color .25s var(--ease);
}
.brand:hover .brand__name { color: #fff; }

/* 窄屏先把名字收起来，只留方标 —— 别跟搜索框抢横向空间 */
@media (max-width: 1180px) {
  .brand__name { display: none; }
}

@media (max-width: 430px) {
  .brand { gap: 0; }
  .brand__mark { width: 24px; height: 24px; }
}

/* ==================================================================
   追加 5：音乐模式分页轮播 + 入口模式组件导航
   ================================================================== */

/* ---------------------- A. 翻页箭头 & 页码点 ----------------------
   箭头常驻 DOM 但透明不可点 —— 鼠标移到左右边缘（JS 判定）才浮现；
   触屏没有 hover，直接给一版常显的淡箭头，否则根本发现不了可以翻页。
   页码点默认更淡，只在翻页后短暂亮一下，不抢图片墙的戏。 */

.wallnav {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s var(--ease), visibility .35s;
}

/* is-ready = 音乐模式且页数 > 1（JS 打） */
.wallnav.is-ready { visibility: visible; }
.wallnav.is-show { opacity: 1; }

.wallnav__btn {
  position: absolute;
  top: 50%;
  width: 50px; height: 50px;
  margin-top: -25px;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .14);
  background: rgba(20, 20, 25, .52);
  color: rgba(245, 245, 247, .92);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  backdrop-filter: blur(20px) saturate(1.35);
  -webkit-backdrop-filter: blur(20px) saturate(1.35);
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .9);
  transition: opacity .3s var(--ease), background .28s var(--ease),
              transform .28s var(--ease), color .28s var(--ease);
}

.wallnav__btn--prev { left: 20px; }
.wallnav__btn--next { right: 20px; }

.wallnav.is-show .wallnav__btn { opacity: 1; pointer-events: auto; }

.wallnav__btn:hover { background: rgba(255, 255, 255, .17); color: #fff; transform: scale(1.07); }
.wallnav__btn:active { transform: scale(.93); }

.wallnav__btn svg {
  width: 22px; height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.walldots {
  position: absolute;
  left: 50%;
  bottom: calc(var(--dock) + 44px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 7px;
  opacity: 0;
  transition: opacity .32s var(--ease);
}

.wallnav.is-show .walldots,
.walldots.is-on { opacity: 1; }

.walldots b {
  display: block;
  width: 6px; height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .34);
  box-shadow: 0 1px 6px rgba(0, 0, 0, .6);
  transition: width .34s var(--ease), background .34s var(--ease);
}

.walldots b.is-on { width: 19px; background: rgba(255, 255, 255, .92); }

/* 触屏：没有 hover，箭头常显淡版，点一下才变实 */
@media (hover: none) {
  .wallnav.is-ready { opacity: 1; }
  .wallnav.is-ready .wallnav__btn { opacity: .55; pointer-events: auto; }
  .wallnav.is-ready .wallnav__btn:active { opacity: 1; }
  .wallnav.is-ready .walldots { opacity: .9; }
}

@media (max-width: 480px) {
  .wallnav__btn { width: 40px; height: 40px; margin-top: -20px; }
  .wallnav__btn--prev { left: 10px; }
  .wallnav__btn--next { right: 10px; }
  .wallnav__btn svg { width: 18px; height: 18px; }
  .walldots { bottom: calc(var(--dock) + 40px + env(safe-area-inset-bottom, 0px)); }
  .walldots b { width: 5px; height: 5px; }
  .walldots b.is-on { width: 15px; }
}

/* 系统关掉动画时别自动翻页（JS 会跳过），箭头和页码点仍然能用 */
@media (prefers-reduced-motion: reduce) {
  .wall__page { transition: none; }
}

/* ---------------------- B. 入口模式：组件导航 ----------------------
   入口模式不放任何图片 —— 背景换成几张「服务路由」大卡。
   卡片竖向节奏：徽标 → 标题 → 说明 → 底栏（路径 + 箭头），状态点浮在右上角。
   整块在视口里垂直居中（margin:auto），所以宽屏下方不再拖出一大片空白。
   ------------------------------------------------------------------- */

body.mode-svc .wall {
  left: 0; top: 0;
  width: 100%; height: 100%;
  transform: none !important;    /* 导航表要能滚，别跟着鼠标视差晃 */
  overflow: hidden;
}

/* 没有照片打底了，给个极淡的中心辉光，纯黑背景才不至于死板 */
body.mode-svc .wall::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(84% 60% at 50% 26%, rgba(78, 92, 130, .20) 0%, rgba(6, 7, 12, 0) 64%),
    radial-gradient(66% 48% at 86% 86%, rgba(56, 74, 96, .14) 0%, rgba(6, 7, 12, 0) 68%);
}

/* 滚动容器同时也是「居中容器」：
   用 flex + 内层 margin:auto —— 内容比视口矮就在正中，
   比视口高（手机竖屏）就自动退化成正常滚动，顶边不会被裁掉。 */
.navgrid {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: calc(var(--top-h) + 30px) 24px calc(var(--dock) + 74px);
}

.navgrid__inner {
  margin: auto;
  width: 100%;
  max-width: 1140px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 18px;
  align-content: start;
}

.navgrid::-webkit-scrollbar { width: 9px; }
.navgrid::-webkit-scrollbar-track { background: transparent; }
.navgrid::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .16);
  border: 2px solid transparent;
  background-clip: padding-box;
  border-radius: 999px;
}
.navgrid::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, .3); background-clip: padding-box; }

/* ---------------------- 卡片 ---------------------- */

.navcard {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  min-height: 196px;
  padding: 24px 24px 20px;
  border-radius: 20px;
  overflow: hidden;
  text-align: left;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  background: rgba(20, 20, 26, .62);
  border: 1px solid rgba(255, 255, 255, .1);
  backdrop-filter: blur(22px) saturate(1.35);
  -webkit-backdrop-filter: blur(22px) saturate(1.35);
  box-shadow: 0 28px 60px -38px rgba(0, 0, 0, .98);
  transition: transform .34s var(--ease), background .34s var(--ease),
              border-color .34s var(--ease), box-shadow .34s var(--ease),
              opacity .3s var(--ease);
}

/* 左上角一层该入口自己的颜色（很淡），不靠图片也能一眼分清 */
.navcard::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(130% 104% at 0% 0%,
    color-mix(in srgb, var(--c1, #64748b) 26%, transparent) 0%, transparent 58%);
  opacity: .8;
  pointer-events: none;
  transition: opacity .34s var(--ease);
}

/* 左边缘一抹双色竖条 */
.navcard::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, var(--c1, #64748b), var(--c2, #1e293b));
}

.navcard:hover {
  transform: translateY(-3px);
  background: rgba(31, 31, 39, .74);
  border-color: rgba(255, 255, 255, .22);
  box-shadow: 0 40px 76px -38px rgba(0, 0, 0, 1);
}
.navcard:hover::after { opacity: 1; }
.navcard:active { transform: translateY(-1px) scale(.994); }
.navcard:focus-visible { outline: 2px solid rgba(255, 255, 255, .55); outline-offset: 3px; }

/* 内容整体压在一个平面上，保证顺序是 光 → 竖条 → 文字 */
.navcard > * { position: relative; z-index: 1; }

/* 运行状态点：浮在右上角，不占流 */
.navcard__dot {
  position: absolute;
  top: 22px; right: 22px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: #22c55e;
  box-shadow: 0 0 0 4px rgba(34, 197, 94, .14);
}

.navcard__mark {
  align-self: flex-start;
  padding: 5px 10px;
  border-radius: 9px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: .07em;
  color: #fff;
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--c1, #64748b) 76%, #0d0f16),
    color-mix(in srgb, var(--c2, #1e293b) 76%, #0d0f16));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .14);
}

.navcard__title {
  margin: 18px 0 0;
  font-size: 17.5px;
  font-weight: 650;
  letter-spacing: -.018em;
  line-height: 1.25;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.navcard__sub {
  margin: 7px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: rgba(245, 245, 247, .58);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.navcard__foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: auto;
  padding-top: 18px;
  min-width: 0;
  border-top: 1px solid rgba(255, 255, 255, .07);
}

.navcard__path {
  min-width: 0;
  max-width: 100%;
  padding: 3px 9px;
  border-radius: 7px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px;
  line-height: 1.6;
  color: rgba(245, 245, 247, .5);
  background: rgba(255, 255, 255, .055);
  border: 1px solid rgba(255, 255, 255, .07);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.navcard__path--none { color: rgba(245, 245, 247, .28); background: none; border-style: dashed; }

.navcard__arrow {
  flex: 0 0 auto;
  margin-left: auto;
  color: rgba(245, 245, 247, .34);
  transition: transform .3s var(--ease), color .3s var(--ease);
}

.navcard__arrow svg {
  display: block;
  width: 16px; height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.navcard:hover .navcard__arrow { color: #fff; transform: translateX(4px); }

/* 停用 / 搜索不匹配 —— 这两条会一起决定灰不灰 */
.navcard.is-off { cursor: not-allowed; }
.navcard.is-off::before { background: rgba(255, 255, 255, .16); }
.navcard.is-off::after { opacity: 0; }
.navcard.is-off .navcard__mark { background: rgba(255, 255, 255, .07); color: rgba(245, 245, 247, .5); box-shadow: none; }
.navcard.is-off .navcard__dot { background: rgba(245, 245, 247, .26); box-shadow: none; }
.navcard.is-off .navcard__title { color: rgba(245, 245, 247, .6); }
.navcard.is-off:hover { transform: none; background: rgba(20, 20, 26, .62); border-color: rgba(255, 255, 255, .1); }
.navcard.is-off:hover .navcard__arrow { color: rgba(245, 245, 247, .34); transform: none; }

.navcard.is-dim { opacity: .26; }

/* 键盘 / 搜索选中：跟 hover 同一观感，但不需要鼠标 */
.navcard.is-cur {
  border-color: rgba(255, 255, 255, .32);
  background: rgba(34, 34, 43, .78);
}

/* ---------------------- 响应式 ---------------------- */

/* 平板：两列，卡片略矮 */
@media (max-width: 1024px) {
  .navgrid__inner { grid-template-columns: repeat(auto-fit, minmax(272px, 1fr)); gap: 16px; }
  .navcard { min-height: 176px; padding: 22px 20px 18px; }
  .navcard__title { margin-top: 15px; font-size: 16.5px; }
  .navcard__dot { top: 20px; right: 20px; }
}

/* 手机：一列，紧凑版（徽标和标题回到一行，省纵向空间） */
@media (max-width: 640px) {
  .navgrid { padding: calc(var(--top-h) + 18px) 14px calc(var(--dock) + 56px); }
  .navgrid__inner { grid-template-columns: 1fr; gap: 11px; }
  .navcard {
    min-height: 0;
    padding: 16px 16px 14px 18px;
    border-radius: 16px;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 10px;
  }
  .navcard__mark { padding: 4px 8px; font-size: 10.5px; }
  /* 标题右边留出一截 —— 状态点还是浮在右上角（缩到三张卡之后，
     点如果留在流末尾会孤零零掉在路径下面一行，很难看） */
  .navcard__title { margin: 0; padding-right: 16px; flex: 1 1 auto; min-width: 0; font-size: 15px; }
  .navcard__dot { top: 17px; right: 16px; }
  .navcard__sub {
    flex: 1 0 100%;
    margin: 8px 0 0;
    font-size: 12.5px;
    -webkit-line-clamp: 2;
  }
  .navcard__foot { flex: 1 0 100%; padding-top: 12px; margin-top: 12px; }
  .navcard__arrow svg { width: 15px; height: 15px; }
}

@media (max-width: 380px) {
  .navcard__path { display: none; }
}

/* 矮视口（笔记本横屏 / 手机横屏）：少留白，卡片压扁一点，别把内容顶出去 */
@media (max-height: 640px) and (min-width: 641px) {
  .navgrid { padding-top: calc(var(--top-h) + 14px); padding-bottom: calc(var(--dock) + 40px); }
  .navcard { min-height: 156px; padding: 18px 20px 16px; }
  .navcard__title { margin-top: 12px; font-size: 16px; }
  .navcard__foot { padding-top: 13px; }
}
