
  /* 字体设置 */
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap');

@font-face {
  font-family: 'Sarasa Gothic';
  src: url('https://cdn.jsdelivr.net/gh/be5invis/Sarasa-Gothic@master/SarasaGothicSC-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
}

body {
  font-family: 'Sarasa Gothic', 'Noto Sans SC', sans-serif;
}

:root {
    /* 夜间模式变量 */
    --card: rgba(10,10,15,0.55);
    --card-hover: rgba(10,10,15,0.75);
    --border: rgba(255,255,255,0.08);
    --text: #e4e4e7;
    --text-muted: rgba(255,255,255,0.76);
    --accent: #6366f1;
    --accent2: #818cf8;
    --overlay-start: rgba(10,10,15,0.3);
    --overlay-end: rgba(10,10,15,0.7);
    --footer-text: rgba(255,255,255,0.72);
    --shadow: rgba(0,0,0,0.2);
    --shadow-hover: rgba(0,0,0,0.3);
    --icon-bg: rgba(255,255,255,0.05);
    --btn-bg: rgba(10,10,15,0.6);
    --btn-text: rgba(255,255,255,0.86);
    --btn-border: rgba(255,255,255,0.1);
    --tab-text: rgba(255,255,255,0.75);
    --tab-hover: rgba(255,255,255,0.08);
    --desc-text: rgba(255,255,255,0.7);
    --avatar-border: rgba(255,255,255,0.2);
    --widget-text: rgba(255,255,255,0.8);
    --contact-bg-qq: rgba(0,150,255,0.15);
    --contact-bg-tg: rgba(0,150,200,0.15);
    --arrow-color: rgba(255,255,255,0.4);
    --card-name: #fff;
    --focus-ring: #fbcfe8;
    --contact-name: #fff;
  }
  
  [data-theme="light"] {
    /* 白天模式变量 */
    --card: rgba(255,255,255,0.45);
    --card-hover: rgba(255,255,255,0.65);
    --border: rgba(255,255,255,0.6);
    --text: #1f2937;
    --text-muted: rgba(0,0,0,0.72);
    --accent: #6366f1;
    --accent2: #818cf8;
    --overlay-start: rgba(255,255,255,0.1);
    --overlay-end: rgba(255,255,255,0.4);
    --footer-text: rgba(0,0,0,0.7);
    --shadow: rgba(0,0,0,0.06);
    --shadow-hover: rgba(0,0,0,0.12);
    --icon-bg: rgba(0,0,0,0.05);
    --btn-bg: rgba(255,255,255,0.5);
    --btn-text: rgba(0,0,0,0.82);
    --btn-border: rgba(255,255,255,0.7);
    --tab-text: rgba(0,0,0,0.72);
    --tab-hover: rgba(0,0,0,0.05);
    --desc-text: rgba(0,0,0,0.6);
    --avatar-border: rgba(0,0,0,0.1);
    --widget-text: rgba(0,0,0,0.75);
    --contact-bg-qq: rgba(0,150,255,0.1);
    --contact-bg-tg: rgba(0,150,200,0.1);
    --arrow-color: rgba(0,0,0,0.35);
    --card-name: #1f2937;
    --focus-ring: #1d4ed8;
    --contact-name: #1f2937;
  }
  
  * { margin:0; padding:0; box-sizing:border-box; }
  :where(a, button):focus-visible {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
  }
  
  /* === 背景图片 === */
  body {
    font-family: 'Noto Sans SC', sans-serif;
    color: var(--text);
    min-height: 100vh;
    overflow-x: hidden;
    display: flex;
    flex-direction: column;
  }
  .bg-image {
      position: fixed;
      inset: 0;
      z-index: 0;
      background-size: cover;
      background-position: center;
      background-repeat: no-repeat;
      opacity: 0;                                  /* 显隐由 JS 交叉淡入淡出控制 */
      transition: opacity 0.9s ease;
      will-change: opacity;
      pointer-events: none;
    }
  /* 背景之上的压暗/渐变遮罩（独立一层） */
  .bg-overlay {
    position: fixed;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background:
      radial-gradient(ellipse at top, rgba(255,255,255,0.05) 0%, transparent 55%),
      linear-gradient(180deg, var(--overlay-start) 0%, var(--overlay-end) 100%);
  }

  /* 底部固定控件组 */
  .fixed-bottom {
    position: fixed;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    right: 20px;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .toggle-wrap {
    display: flex;
    min-height: 44px;
    cursor: pointer;
    align-items: center;
    gap: 6px;
    background: var(--btn-bg);
    border: 1px solid var(--btn-border);
    border-radius: 8px;
    padding: 4px 10px 4px 8px;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
  }
  .toggle-label {
    font-size: 12px;
    color: var(--btn-text);
    user-select: none;
    white-space: nowrap;
  }
  /* Toggle 开关 */
  .switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 28px;
    flex-shrink: 0;
  }
  .switch input { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%; cursor: pointer; }
  .slider {
    position: absolute;
    inset: 0;
    background: rgba(255,255,255,0.2);
    border-radius: 28px;
    cursor: pointer;
    transition: background 0.25s;
  }
  .slider::before {
    content: '';
    position: absolute;
    width: 24px;
    height: 24px;
    left: 2px;
    top: 2px;
    background: #fff;
    border-radius: 50%;
    transition: transform 0.25s;
  }
  .switch input:checked + .slider { background: var(--accent); }
  .switch input:checked + .slider::before { transform: translateX(16px); }
  .switch input:focus-visible + .slider {
    outline: 3px solid var(--focus-ring);
    outline-offset: 3px;
  }
  .fixed-bottom button {
    width: 44px;
    height: 44px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--btn-bg);
    border: 1px solid var(--btn-border);
    border-radius: 8px;
    color: var(--btn-text);
    font-size: 18px;
    cursor: pointer;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    transition: all 0.2s;
  }
  .fixed-bottom button:hover {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
  }
  
  /* 主内容区 */
  .container {
    position: relative;
    z-index: 1;
    max-width: 720px;
    margin: 0 auto;
    padding: 40px 20px;
    flex: 1;
    display: flex;
    flex-direction: column;
  }
  /* 亚克力大卡片（夜晚模式） */
    .glass-card {
      position: relative;
      background:
        linear-gradient(180deg,
          rgba(20,22,38,0.62) 0%,
          rgba(16,18,32,0.72) 40%,
          rgba(12,14,26,0.78) 100%);
      border: 1px solid rgba(255,255,255,0.09);
      border-radius: 24px;
      backdrop-filter: blur(48px) saturate(140%);
      -webkit-backdrop-filter: blur(48px) saturate(140%);
      box-shadow:
        0 24px 64px rgba(0,0,0,0.5),
        0 8px 24px var(--shadow),
        inset 0 1px 0 rgba(255,255,255,0.12),
        inset 0 -1px 0 rgba(255,255,255,0.02);
      padding: 24px 20px;
      margin-top: 24px;
      flex: 1;
      display: flex;
      flex-direction: column;
    }
    /* 亚克力顶部高光线 */
    .glass-card::before {
      content: '';
      position: absolute;
      top: 0;
      left: 8%;
      right: 8%;
      height: 1px;
      background: linear-gradient(90deg, transparent, rgba(255,255,255,0.28), transparent);
      pointer-events: none;
    }
  
  /* === 头部区域 === */
  .header {
    text-align: center;
    margin-bottom: 30px;
  }
  .avatar-wrap {
    position: relative;
    display: inline-block;
    margin-bottom: 16px;
  }
  .avatar {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    border: 3px solid var(--avatar-border);
    box-shadow: 0 8px 32px var(--shadow);
    object-fit: cover;
    transition: transform 0.3s, box-shadow 0.3s;
  }
  .avatar:hover {
    transform: scale(1.05);
    box-shadow: 0 8px 32px rgba(99,102,241,0.4);
    border-color: var(--accent);
  }
  .header h1 {
    font-size: 32px;
    font-weight: 700;
    color: transparent;
    background: linear-gradient(135deg, #FFFFFF 0%, #FFF8DC 25%, #FFE5F0 60%, #FFB6C1 100%);
    -webkit-background-clip: text;
    background-clip: text;
    text-shadow: 
      0 1px 1px rgba(0,0,0,0.15),
      0 2px 8px rgba(245,222,179,0.3);
    margin-bottom: 6px;
    filter: drop-shadow(0 1px 2px rgba(245,222,179,0.3));
  }
  .header .desc {
    color: transparent;
    background: linear-gradient(135deg, #FFF8DC 0%, #FAF0E6 30%, #FFB6C1 70%, #FF69B4 100%);
    -webkit-background-clip: text;
    background-clip: text;
    font-size: 14px;
    font-weight: 300;
    display: inline-block;
  }

  .header .desc span {
    display: inline-block;
    color: transparent;
    background: linear-gradient(135deg, #FFF8DC 0%, #FAF0E6 30%, #FFB6C1 70%, #FF69B4 100%);
    -webkit-background-clip: text;
    background-clip: text;
    animation: floatUpDown 3s ease-in-out infinite;
  }

  .header .desc span:nth-child(1) { animation-delay: 0s; }
  .header .desc span:nth-child(2) { animation-delay: 0.3s; }
  .header .desc span:nth-child(3) { animation-delay: 0.6s; }
  .header .desc span:nth-child(4) { animation-delay: 0.9s; }
  .header .desc span:nth-child(5) { animation-delay: 1.2s; }
  .header .desc span:nth-child(6) { animation-delay: 1.5s; }
  .header .desc span:nth-child(7) { animation-delay: 1.8s; }
  /* 「·收藏本页面防失联」也要和前七个字一样依次起伏，之前只写到第 7 个，
     后面九个字全都用默认的 0s 延迟，结果整块一起上下动，看着像一坨 */
  .header .desc span:nth-child(8) { animation-delay: 2.1s; }
  .header .desc span:nth-child(9) { animation-delay: 2.4s; }
  .header .desc span:nth-child(10) { animation-delay: 2.7s; }
  .header .desc span:nth-child(11) { animation-delay: 3s; }
  .header .desc span:nth-child(12) { animation-delay: 3.3s; }
  .header .desc span:nth-child(13) { animation-delay: 3.6s; }
  .header .desc span:nth-child(14) { animation-delay: 3.9s; }
  .header .desc span:nth-child(15) { animation-delay: 4.2s; }
  .header .desc span:nth-child(16) { animation-delay: 4.5s; }

  @keyframes floatUpDown {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-4px); }
  }
  
  /* === 时间/天气小组件 === */
  .widget-bar {
    display: flex;
    justify-content: center;
    gap: 12px;
    margin-bottom: 24px;
    flex-wrap: wrap;
  }
  .mini-widget {
        background: linear-gradient(160deg, rgba(15,17,30,0.3) 0%, rgba(10,12,20,0.35) 100%);
        border: 1px solid rgba(255,255,255,0.05);
        border-radius: 14px;
        padding: 8px 16px;
        display: flex;
      align-items: center;
      gap: 8px;
      font-size: 13px;
      color: var(--widget-text);
      backdrop-filter: blur(28px) saturate(120%);
      -webkit-backdrop-filter: blur(28px) saturate(120%);
      box-shadow:
        0 4px 16px var(--shadow),
        inset 0 1px 0 rgba(255,255,255,0.04);
    }
  .mini-widget .icon { font-size: 16px; }
  .mini-widget .time { font-size: 15px; font-weight: 500; }
  .mini-widget .divider { color: var(--text-muted); margin: 0 4px; }
  
  /* === 标签切换 === */
  .tabs {
        display: flex;
        gap: 4px;
        background: linear-gradient(160deg, rgba(15,17,30,0.3) 0%, rgba(10,12,20,0.35) 100%);
        border: 1px solid rgba(255,255,255,0.05);
        border-radius: 14px;
        padding: 4px;
        margin-bottom: 20px;
        width: fit-content;
        margin-left: auto;
        margin-right: auto;
        backdrop-filter: blur(12px) saturate(100%);
        -webkit-backdrop-filter: blur(12px) saturate(100%);
      box-shadow:
        0 4px 16px var(--shadow),
        inset 0 1px 0 rgba(255,255,255,0.1);
    }
  .tab-btn {
    padding: 8px 24px;
    border: none;
    background: transparent;
    color: var(--tab-text);
    font-size: 14px;
    font-family: inherit;
    border-radius: 9px;
    cursor: pointer;
    transition: all 0.25s;
    font-weight: 400;
  }
  .tab-btn.active {
    background: var(--accent);
    color: #fff;
    font-weight: 500;
    box-shadow: 0 4px 12px rgba(99,102,241,0.3);
  }
  .tab-btn:not(.active):hover {
    color: #fff;
    background: var(--tab-hover);
  }
  
  /* === 内容区 === */
  .tab-content { display: none; }
  .tab-content.active { display: block; }
  
  /* === 导航网格 === */
  .link-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
  }
  /* 列数上限：data-cols 由 index.html 顶部的 NAV_LINKS 数量算出并写入
     1~8 → 2 列   9~15 → 3 列（9 个即 3×3）   16+ → 4 列（16 个即 4×4）
     （也可用 NAV_COLUMNS 手动锁定）
     实际列数还要再看屏幕档位，见文件底部「导航响应式」一节。
     多出来的列全靠「内容区向两侧扩展」放下，卡片尺寸自始至终不缩。 */
  .link-grid[data-cols="1"] { grid-template-columns: minmax(0, 1fr); }
  .link-grid[data-cols="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .link-grid[data-cols="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .link-grid[data-cols="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* 内容区向两侧扩展（body[data-nav-cols] 由渲染脚本写入）
     左右必须留出死区，不能压到两个固定浮层上：
       看板娘 .live2d-wrap  right: 0，     宽 min(40vw, 380px)
       播放器               left: 16px，   宽 280px
     --nav-safe 取 390px（380 + 10 缝隙），内容区两侧各让出这么多。

       max-width = min( 理想宽度 , max( 保底宽度 , 视口 - 死区 × 2 ) )

     · 4 列只在 ≥1920px 出现，1920 - 780 = 1140px 已经够宽，死区永远留得住；
     · 3 列会下探到 1025px，760px 是保底值，此时死区会被迫变窄，但 3 列本来就不算宽。
     卡片尺寸不跟着缩：上面的宽度保证每张卡至少 220px，
     图标仍是 48px、标题 15px、描述两行，和 2 列时完全一致。 */
  body[data-nav-cols="3"],
  body[data-nav-cols="4"] { --nav-safe: 390px; }
  body[data-nav-cols="3"] .container {
    max-width: min(1040px, max(760px, calc(100vw - var(--nav-safe) * 2)));
  }
  body[data-nav-cols="4"] .container {
    max-width: min(1370px, calc(100vw - var(--nav-safe) * 2));
  }
  /* 没有配图标时用名称首字/emoji 兜底 */
  .link-card .card-icon.is-text {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    line-height: 1;
    color: var(--card-name);
  }
  .link-card {
      background: linear-gradient(160deg, rgba(15,17,30,0.3) 0%, rgba(10,12,20,0.35) 100%);
      border: 1px solid rgba(255,255,255,0.05);
      border-radius: 18px;
      padding: 16px;
      display: flex;
      align-items: center;
      gap: 14px;
      text-decoration: none;
      color: var(--text);
      transition: all 0.25s;
      backdrop-filter: blur(30px) saturate(110%);
      -webkit-backdrop-filter: blur(30px) saturate(110%);
      box-shadow:
        0 4px 16px var(--shadow),
        inset 0 1px 0 rgba(255,255,255,0.04);
    }
    .link-card:hover {
          background: linear-gradient(160deg, rgba(20,22,40,0.4) 0%, rgba(15,17,30,0.45) 100%);
          border-color: rgba(255,255,255,0.08);
          transform: translateY(-2px);
          box-shadow:
        0 10px 32px var(--shadow-hover),
        inset 0 1px 0 rgba(255,255,255,0.08);
    }
  .link-card .card-icon {
    width: 48px;
    height: 48px;
    border-radius: 50%; /* 圆形图标，改回圆角方形改12px或删除此行 */
    overflow: hidden;
    flex-shrink: 0;
    background: var(--icon-bg);
  }
  .link-card .card-icon img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .link-card .card-info { flex: 1; min-width: 0; }
  .link-card .card-name {
    font-size: 15px;
    font-weight: 500;
    margin-bottom: 3px;
    color: var(--card-name);
  }
  .link-card .card-desc {
    font-size: 12px;
    color: var(--text-muted);
    line-height: 1.5;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    white-space: normal;
    word-break: break-word;
  }
  .link-card .arrow {
    color: var(--arrow-color);
    font-size: 14px;
    transition: transform 0.2s, color 0.2s;
  }
  .link-card:hover .arrow {
    color: var(--accent2);
    transform: translateX(3px);
  }
  
  /* 一言 */
  .hitokoto {
    display: block;
    width: 100%;
    border: 0;
    font-family: inherit;
    text-align: center;
    padding: 8px 16px;
    margin-bottom: 16px;
    font-size: 13px;
    color: transparent;
    background: linear-gradient(135deg, #FFF8DC 0%, #FFE5F0 50%, #FFC0CB 100%);
    -webkit-background-clip: text;
    background-clip: text;
    cursor: pointer;
    border-radius: 8px;
    transition: color 0.2s, background 0.2s;
    line-height: 1.6;
    user-select: none;
  }
  .hitokoto:hover { filter: brightness(1.15); }
  /* === 逐字歌词：音乐播放时接管一言的位置（assets/lyrics.js） === */
  /* 一言用的是父级 background-clip:text 渐变，歌词层要自带背景，
     所以接管时先把父级那层渐变关掉，交给 .hk-lyric 自己画。 */
  .hitokoto .hk-lyric-box { display: none; }
  .hitokoto.is-lyric {
    background: none;
    -webkit-background-clip: border-box;
    background-clip: border-box;
    color: inherit;
    cursor: default;
  }
  .hitokoto.is-lyric .hk-text { display: none; }
  /* 两行歌词整体显示，并向上收一点，补偿多出来的一行高度 */
  .hitokoto.is-lyric .hk-lyric-box {
    display: inline-block;
    transform: translateY(-6px);
  }
  /* --lrc-p 由 JS 每帧写入（0%~100%），硬边渐变就是「已唱 / 未唱」的分界线，
     边界扫过文字即卡拉 OK 的逐字填充效果。 */
  .hk-lyric {
    --lrc-p: 0%;
    --lrc-done: #ffd3e1;
    --lrc-todo: rgba(255, 255, 255, 0.34);
    display: block;
    max-width: 100%;
    font-size: 15px;
    font-weight: 500;
    letter-spacing: 0.02em;
    background-image: linear-gradient(90deg,
      var(--lrc-done) 0 var(--lrc-p),
      var(--lrc-todo) var(--lrc-p) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    text-shadow: none;
    animation: lrcLineIn 0.32s ease both;
  }
  /* 下一行：暗色预告，不参与填充 */
  .hk-lyric-next {
    --lrc-next: rgba(255, 255, 255, 0.5);
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--lrc-next);
  }
  @keyframes lrcLineIn {
    from { opacity: 0; transform: translateY(3px); }
    to   { opacity: 1; transform: none; }
  }
  /* 白天模式：浅背景下未唱部分要压得住，用深色 */
  [data-theme="light"] .hitokoto.is-lyric { color: inherit; }
  [data-theme="light"] .hk-lyric {
    --lrc-done: #be185d;
    --lrc-todo: rgba(15, 23, 42, 0.32);
  }
  [data-theme="light"] .hk-lyric-next {
    --lrc-next: rgba(15, 23, 42, 0.45);
  }
  /* 不支持 background-clip:text 的浏览器：整行直接用已唱色，不做填充 */
  @supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    .hk-lyric { color: var(--lrc-done); background-image: none; }
  }
  @media (prefers-reduced-motion: reduce) {
    .hk-lyric { animation: none; }
  }
  /* 白天模式的小字号一言用稳固实色，避免浅背景上渐变文字对比不足。 */
  [data-theme="light"] .hitokoto { color: #075985; background: transparent; }
  [data-theme="light"] .hitokoto.hitokoto-alt { color: #9a3412; }
  /* 白天模式标题与副标题：主标题紫蓝渐变+3D阴影，副标题深色渐变 */
  html[data-theme="light"] .header h1 {
    background: linear-gradient(135deg, #831843 0%, #9d174d 25%, #7e22ce 60%, #6b21a8 100%) !important;
    -webkit-background-clip: text !important;
    background-clip: text !important;
    -webkit-text-fill-color: transparent !important;
    color: transparent !important;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.08), 0 2px 8px rgba(236, 72, 153, 0.15) !important;
    filter: drop-shadow(0 1px 2px rgba(236, 72, 153, 0.15)) !important;
    margin-bottom: 6px !important;
  }
  [data-theme="light"] .header .desc {
    background: linear-gradient(135deg, #5b21b6 0%, #6d28d9 50%, #9d174d 100%) !important;
    -webkit-background-clip: text !important;
    background-clip: text !important;
    color: transparent !important;
  }
  [data-theme="light"] .header .desc span {
    background: linear-gradient(135deg, #5b21b6 0%, #6d28d9 50%, #9d174d 100%) !important;
    -webkit-background-clip: text !important;
    background-clip: text !important;
    color: transparent !important;
  }

  /* === 联系区 === */
  .contact-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
  }
  .contact-card {
      background: linear-gradient(160deg, rgba(15,17,30,0.3) 0%, rgba(10,12,20,0.35) 100%);
      border: 1px solid rgba(255,255,255,0.05);
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
      box-shadow: 0 2px 8px rgba(0,0,0,0.2);
      border-radius: 18px;
      padding: 16px 20px;
      display: flex;
      align-items: center;
      gap: 14px;
      text-decoration: none;
      color: var(--text);
      transition: all 0.25s;
      backdrop-filter: blur(30px) saturate(110%);
      -webkit-backdrop-filter: blur(30px) saturate(110%);
      box-shadow:
        0 4px 16px var(--shadow),
        inset 0 1px 0 rgba(255,255,255,0.04);
    }
    .contact-card:hover {
              background: linear-gradient(160deg, rgba(20,22,40,0.4) 0%, rgba(15,17,30,0.45) 100%);
              border-color: rgba(255,255,255,0.08);
              transform: translateY(-2px);
              box-shadow:
                0 10px 32px rgba(0,0,0,0.3),
                inset 0 1px 0 rgba(255,255,255,0.04);
    }
  .contact-icon {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    flex-shrink: 0;
    overflow: hidden;
  }
  .contact-icon img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
  .contact-icon.qq { background: var(--contact-bg-qq); }
  .contact-icon.qqgrp { background: var(--contact-bg-qq); }
  .contact-icon.tg { background: var(--contact-bg-tg); }
  .contact-info { flex: 1; }
  .contact-name { font-weight: 500; margin-bottom: 2px; color: var(--contact-name); }
  .contact-desc { font-size: 12px; color: var(--text-muted); }
  
  /* === 页脚 === */
  .footer {
    text-align: center;
    padding: 20px;
    font-size: 12px;
    color: var(--footer-text);
    margin-top: auto;
  }
  .footer a {
    color: var(--footer-text);
    text-decoration: none;
    transition: color 0.2s;
  }
  .footer a:hover {
    color: var(--accent);
  }
  #uptime {
    background: linear-gradient(90deg, #fbcfe8, #f9a8d4, #e879f9, #c084fc);
    background-size: 300% 100%;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    animation: gradientShift 4s ease infinite;
  }
  @keyframes gradientShift {
    0% { background-position: 0% 50%; }
    50% { background-position: 100% 50%; }
    100% { background-position: 0% 50%; }
  }
  
  /* === 响应式 === */
  /* 导航响应式：列数只跟屏幕档位走，卡片尺寸自始至终不变。

       ≥ 1920px        最多 4 列  →  16 个 = 4 × 4
       1025 ~ 1919px   最多 3 列  →   9 个 = 3 × 3
       ≤ 1024px        最多 2 列  ←  改造前的老规矩，平板 / 手机一点没动
       ≤ 420px         单列长条   ←  同上，竖屏手机放不下两列时

     实际列数 = min( 按导航数量算出的列数 , 当前屏幕档位允许的最大列数 )。
     所以 8 个导航在任何屏幕上都还是老样子的 2 列。
     下面统一用 body[data-nav-cols=N] .xxx 的写法保持相同优先级，靠书写顺序决定谁生效，
     别改成 .link-grid[data-cols] 否则优先级会打架。 */
  @media (max-width: 1919px) {
    /* 不到 1920px：4 列降为 3 列，容器改用 3 列那条规则 */
    body[data-nav-cols="4"] .container {
      max-width: min(1040px, max(760px, calc(100vw - var(--nav-safe) * 2)));
    }
    body[data-nav-cols="4"] .link-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  }
  @media (max-width: 1024px) {
    /* 平板 / 手机：回到改造前的 2 列，容器还原成 720px */
    body[data-nav-cols="3"] .container,
    body[data-nav-cols="4"] .container { max-width: 720px; }
    body[data-nav-cols="3"] .link-grid,
    body[data-nav-cols="4"] .link-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
  @media (max-width: 640px) {
    .container {
      padding: 20px 16px calc(88px + env(safe-area-inset-bottom, 0px));
      margin-top: 16px;
      margin-bottom: 0;
    }
    .header h1 { font-size: 24px; }
    .glass-card { padding: 16px 12px; }
  }
  @media (max-width: 420px) {
    .container { padding-left: 14px; padding-right: 14px; }
    .header { margin-bottom: 16px; }
    .header .desc { font-size: 12px; line-height: 1.6; }
    .widget-bar { margin-bottom: 16px; }
    /* 窄屏手机：和改造前一样，统一单列长条 */
    .link-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
    body[data-nav-cols] .link-grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
    .link-card { min-height: 72px; padding: 12px 14px; }
  }

  /* ===== 白天模式覆盖：简洁浅色 ===== */
  [data-theme="light"] {
    /* 背景遮罩 */
    --overlay-start: rgba(255,255,255,0.45);
    --overlay-end: rgba(255,255,255,0.7);
  }
  [data-theme="light"] .glass-card {
    background: rgba(255,255,255,0.42);
    border: 1px solid rgba(255,255,255,0.65);
    border-radius: 20px;
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow:
      0 8px 32px rgba(0,0,0,0.08),
      inset 0 1px 0 rgba(255,255,255,0.6);
    padding: 24px 20px;
  }
  [data-theme="light"] .glass-card::before { display: none; }
  [data-theme="light"] .mini-widget {
    background: rgba(255,255,255,0.45);
    border: 1px solid rgba(255,255,255,0.6);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  }
  [data-theme="light"] .tabs {
    background: rgba(255,255,255,0.45);
    border: 1px solid rgba(255,255,255,0.6);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  }
  [data-theme="light"] .link-card {
    background: rgba(255,255,255,0.4);
    border: 1px solid rgba(255,255,255,0.55);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  }
  [data-theme="light"] .link-card:hover {
    background: rgba(255,255,255,0.85);
    border-color: rgba(255,255,255,1);
    box-shadow: 0 4px 16px rgba(0,0,0,0.1);
  }
  [data-theme="light"] .contact-card {
    background: rgba(255,255,255,0.4);
    border: 1px solid rgba(255,255,255,0.55);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 2px 8px rgba(0,0,0,0.06);
  }
  [data-theme="light"] .contact-card:hover {
    background: rgba(255,255,255,0.85);
    border-color: rgba(255,255,255,1);
  }

  /* 公祭日灰色 */
  html.mourning, html.mourning * {
    filter: grayscale(100%) !important;
  }

  /* 樱花容器 */
  #sakura-container {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 2;
    overflow: hidden;
  }
  .sakura-petal {
    position: absolute;
    top: -10vh;
    width: 16px;
    height: 20px;
    opacity: 0.85;
    transform: rotate(0deg);
    animation: sakuraFall linear forwards;
    filter: drop-shadow(0 2px 3px rgba(0,0,0,0.12));
    user-select: none;
    pointer-events: none;
    background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 120'><path d='M50 5 C 20 15, 5 45, 30 70 C 45 85, 55 85, 70 70 C 95 45, 80 15, 50 5 Z' fill='%23ffd6e7' stroke='%23ff9ec2' stroke-width='1'/></svg>") no-repeat center / contain;
  }
  @keyframes sakuraFall {
    0% { transform: translate3d(0,0,0) rotate(0deg); opacity: 0.9; }
    50% { transform: translate3d(calc(var(--drift,0) * 1px), 55vh,0) rotate(180deg); opacity: 1; }
    100% { transform: translate3d(calc(var(--drift,0) * 2px), 110vh,0) rotate(720deg); opacity: 0.3; }
  }

  /* 粒子画布 */
  #particles-canvas {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 2;
  }

  /* 网易云播放器 左下角 */
  .music-player {
    position: fixed;
    left: 20px;
    bottom: 20px;
    z-index: 10;
    background: var(--btn-bg);
    border: 1px solid var(--btn-border);
    border-radius: 12px;
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    padding: 3px;
    box-shadow: 0 4px 16px var(--shadow);
    width: 280px;
  }
  /* APlayer 样式按需载入后，保留多行标题与自然高度。 */
  .aplayer .aplayer-info { height: auto !important; min-height: 66px !important; }
  .aplayer .aplayer-info .aplayer-music {
    overflow: visible !important;
    white-space: normal !important;
    text-overflow: unset !important;
    height: auto !important;
    line-height: 1.5 !important;
    margin-bottom: 8px !important;
  }
  .aplayer .aplayer-info .aplayer-music .aplayer-title,
  .aplayer .aplayer-info .aplayer-music .aplayer-author {
    white-space: normal !important;
    display: inline !important;
  }
  /* === 播放器顶部的歌单选择（assets/player.js 生成）：点「🎶 歌单」展开，播放器底部固定，菜单往上长 === */
  .pl-picker { margin: 0 0 3px; font-size: 13px; color: var(--btn-text); }
  .pl-current {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    min-height: 32px;
    padding: 5px 10px;
    font: inherit;
    color: inherit;
    text-align: left;
    background: rgba(255,255,255,0.06);
    border: 1px solid var(--btn-border);
    border-radius: 9px;
    cursor: pointer;
    transition: background .2s, border-color .2s;
  }
  .pl-current:hover,
  .pl-current:focus-visible,
  .pl-picker.is-open .pl-current { background: rgba(255,143,171,0.16); border-color: rgba(255,143,171,0.55); outline: none; }
  .pl-name { flex: 1 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: 500; }
  .pl-count { flex: none; font-size: 12px; opacity: .7; }
  .pl-caret { flex: none; font-size: 11px; opacity: .8; transition: transform .2s; }
  .pl-picker.is-open .pl-caret { transform: rotate(180deg); }
  .pl-picker.is-loading .pl-name { opacity: .75; }
  .pl-menu {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin-top: 4px;
    padding: 4px;
    background: rgba(0,0,0,0.12);
    border: 1px solid var(--btn-border);
    border-radius: 9px;
  }
  .pl-menu[hidden] { display: none; }
  .pl-opt {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 1px;
    width: 100%;
    padding: 6px 10px 6px 26px;
    font: inherit;
    color: inherit;
    text-align: left;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 7px;
    cursor: pointer;
    transition: background .2s, border-color .2s;
  }
  .pl-opt::before {                    /* 单选圆点 */
    content: '';
    position: absolute;
    left: 9px;
    top: 11px;
    width: 9px;
    height: 9px;
    border: 1.5px solid currentColor;
    border-radius: 50%;
    opacity: .55;
    box-sizing: border-box;
  }
  .pl-opt[aria-checked="true"] { background: rgba(255,143,171,0.16); border-color: rgba(255,143,171,0.45); }
  .pl-opt[aria-checked="true"]::before { background: #ff8fab; border-color: #ff8fab; opacity: 1; }
  .pl-opt:not(:disabled):hover,
  .pl-opt:focus-visible { background: rgba(255,255,255,0.08); outline: none; }
  .pl-opt:disabled { cursor: wait; }
  .pl-opt.is-loading .pl-opt-label::after { content: ' · 加载中…'; font-weight: 400; opacity: .7; }
  .pl-opt-label { font-weight: 500; }
  .pl-opt-desc { font-size: 11.5px; line-height: 1.4; opacity: .68; overflow-wrap: anywhere; }
  .pl-form { display: flex; gap: 4px; padding: 0 2px 2px 26px; }
  .pl-platform,
  .pl-input,
  .pl-go {
    min-width: 0;
    height: 30px;
    padding: 0 8px;
    font: inherit;
    font-size: 12.5px;
    color: inherit;
    background: rgba(255,255,255,0.08);
    border: 1px solid var(--btn-border);
    border-radius: 7px;
  }
  .pl-platform { flex: none; padding-right: 4px; cursor: pointer; }
  .pl-platform option { color: #1f2937; background: #fff; }
  .pl-input { flex: 1 1 auto; }
  .pl-input::placeholder { color: inherit; opacity: .55; }
  .pl-platform:focus-visible,
  .pl-input:focus { outline: 2px solid rgba(255,143,171,0.6); outline-offset: 0; }
  .pl-go { flex: none; color: #fff; background: #ff8fab; border-color: #ff8fab; cursor: pointer; }
  .pl-go:hover:not(:disabled) { background: #f57396; }
  .pl-go:disabled { opacity: .65; cursor: wait; }
  .pl-msg { margin: 0; padding: 0 4px 0 28px; font-size: 11.5px; line-height: 1.45; opacity: .8; }
  .pl-msg:empty { display: none; }
  .pl-msg.is-error { color: #fb7185; opacity: 1; }
  [data-theme="light"] .pl-current { background: rgba(255,255,255,0.45); }
  [data-theme="light"] .pl-menu { background: rgba(255,255,255,0.35); }
  [data-theme="light"] .pl-platform,
  [data-theme="light"] .pl-input { background: rgba(255,255,255,0.7); }
  [data-theme="light"] .pl-msg.is-error { color: #e11d48; }
  @media (max-width: 640px) {
    .pl-platform, .pl-input, .pl-go { height: 34px; font-size: 16px; }   /* iOS 输入框字号 < 16px 聚焦会自动放大页面 */
    .pl-opt { padding-top: 8px; padding-bottom: 8px; }
    .pl-opt::before { top: 13px; }
  }
  /* 歌词背景透明 */
  .aplayer .aplayer-lrc {
    background: transparent !important;
  }
  .aplayer .aplayer-lrc .aplayer-lrc-contents {
    background: transparent !important;
  }

  /* === Live2D 看板娘（右下角，仿原版 live2d-widget 的气泡 + 工具栏） === */
  .live2d-wrap {
    position: fixed;
    right: 0;
    bottom: 8px;                      /* 底部控件条此时已收进工具栏 */
    z-index: 5;                       /* 低于 .fixed-bottom(10) */
    width: min(40vw, 380px);          /* 比人物宽一些：翅膀 / 头发摆动时不被裁掉 */
    height: min(50vh, 440px);
    pointer-events: none;             /* 模型区域不挡页面点击，只有工具栏可点 */
  }
  .live2d-wrap[hidden] { display: none; }
  .live2d-canvas {
    display: block;
    width: 100%;
    height: 100%;
  }
  .waifu-tips {
    position: absolute;                /* 位置由 live2d.js 贴着模型头顶计算 */
    top: 0;
    right: 40px;
    width: min(250px, 30vw);
    min-height: 70px;
    padding: 5px 10px;
    box-sizing: border-box;
    font-size: 14px;
    line-height: 24px;
    color: #4a3f35;
    word-break: break-all;
    background-color: rgba(236, 217, 188, .5);
    border: 1px solid rgba(224, 186, 140, .62);
    border-radius: 12px;
    box-shadow: 0 3px 15px 2px rgba(191, 158, 118, .2);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    opacity: 0;
    transition: opacity 1s;
    animation: waifu-shake 50s ease-in-out 5s infinite;
  }
  .waifu-tips.waifu-tips-active { opacity: 1; transition: opacity .2s; }
  /* 带选项的气泡（音乐询问 / 换装菜单）要能点，其余时候气泡不挡鼠标 */
  .waifu-tips { pointer-events: none; }
  .waifu-tips.waifu-tips-active.has-choices { pointer-events: auto; animation: none; }
  .waifu-choices { display: none; gap: 6px; margin: 6px 0 2px; flex-wrap: wrap; }
  .waifu-tips.has-choices .waifu-choices { display: flex; }
  .waifu-choice {
    flex: 1 1 auto;
    padding: 2px 10px;
    font: inherit;
    font-size: 13px;
    line-height: 22px;
    color: #5b4636;
    background: rgba(255, 255, 255, .55);
    border: 1px solid rgba(224, 186, 140, .8);
    border-radius: 8px;
    cursor: pointer;
    transition: background .2s, color .2s;
  }
  .waifu-choice:hover,
  .waifu-choice:focus-visible { background: rgba(255, 255, 255, .85); color: #0684bd; outline: none; }
  .waifu-choice.is-primary { color: #fff; background: #e0a060; border-color: #e0a060; }
  .waifu-choice.is-primary:hover,
  .waifu-choice.is-primary:focus-visible { color: #fff; background: #d08a40; }
  .waifu-number { display: flex; flex: 1 1 100%; gap: 6px; margin: 0; }
  .waifu-number input {
    flex: 1 1 auto;
    min-width: 0;
    padding: 2px 8px;
    font: inherit;
    font-size: 13px;
    line-height: 22px;
    color: #5b4636;
    background: rgba(255, 255, 255, .7);
    border: 1px solid rgba(224, 186, 140, .8);
    border-radius: 8px;
  }
  .waifu-number input:focus { outline: 2px solid rgba(6, 132, 189, .5); outline-offset: 0; }
  .waifu-number .waifu-choice { flex: 0 0 auto; }
  [data-theme="light"] .waifu-tips { color: #3b2f25; background-color: rgba(236, 217, 188, .75); }
  .waifu-tool {
    position: absolute;
    right: 6px;                       /* 模型右侧，贴底排列，下方不留空 */
    bottom: 10px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    opacity: .7;
    transition: opacity .6s;
    pointer-events: auto;
  }
  .waifu-tool:hover,
  .waifu-tool:focus-within { opacity: 1; }
  .waifu-tool button {
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
  }
  .waifu-tool button[hidden] { display: none; }
  .waifu-tool button[aria-pressed="false"] svg { opacity: .55; }
  /* 看板娘显示时，底部控件条（随机背景 / 主题）已收进工具栏 */
  body.waifu-on .fixed-bottom { display: none; }
  .waifu-tool svg {
    width: 24px;
    height: 24px;
    fill: #7b8c9d;
    transition: fill .3s;
    filter: drop-shadow(0 0 2px rgba(255, 255, 255, .6));
  }
  .waifu-tool button:hover svg,
  .waifu-tool button:focus-visible svg { fill: #0684bd; }
  /* 退出后贴在右侧的小标签，悬停滑出，点击召回 */
  .waifu-toggle {
    position: fixed;
    right: 0;
    bottom: 140px;
    z-index: 6;
    width: 60px;
    margin-right: -100px;
    padding: 5px 5px 5px 2px;
    font-size: 12px;
    color: #fff;
    background-color: #fa0;
    border: 0;
    border-radius: 5px;
    writing-mode: vertical-rl;
    text-align: left;
    cursor: pointer;
    transition: margin-right 1s;
  }
  .waifu-toggle.waifu-toggle-active { margin-right: -38px; }
  .waifu-toggle.waifu-toggle-active:hover,
  .waifu-toggle.waifu-toggle-active:focus-visible { margin-right: -20px; }
  @keyframes waifu-shake {
    2% { transform: translate(.5px, -1.5px) rotate(-.5deg); }
    4% { transform: translate(.5px, 1.5px) rotate(1.5deg); }
    6% { transform: translate(1.5px, 1.5px) rotate(1.5deg); }
    8% { transform: translate(2.5px, 1.5px) rotate(.5deg); }
    10% { transform: translate(.5px, 2.5px) rotate(.5deg); }
    12% { transform: translate(1.5px, 1.5px) rotate(.5deg); }
    14% { transform: translate(.5px, .5px) rotate(.5deg); }
    16% { transform: translate(-1.5px, -.5px) rotate(1.5deg); }
    18% { transform: translate(.5px, .5px) rotate(1.5deg); }
    20% { transform: translate(2.5px, 2.5px) rotate(1.5deg); }
    0%, 22%, 100% { transform: translate(0, 0) rotate(0); }
  }
  @media (prefers-reduced-motion: reduce) {
    .waifu-tips { animation: none; }
  }
  /* 手机上不加载看板娘（省流量，也不跟播放器挤） */
  @media (max-width: 640px) {
    .live2d-wrap,
    .waifu-toggle { display: none; }
  }
  /* 触摸屏（平板）：人物身上的透明触摸区，点一下弹音乐菜单；位置由 live2d.js 按人物外框计算 */
  .waifu-tips,
  .waifu-tool { z-index: 2; }            /* 气泡、工具栏压在触摸区上面 */
  .waifu-touch-zone {
    position: absolute;
    z-index: 1;
    background: transparent;
    cursor: pointer;                   /* iOS Safari 只给「可点」的元素派发 click */
    pointer-events: auto;
    touch-action: manipulation;        /* 去掉双击缩放带来的点击延迟，照样能滑动页面 */
    -webkit-tap-highlight-color: transparent;
  }
  .waifu-touch-zone[hidden] { display: none; }
  /* 触摸屏没有悬停：工具栏常亮、按钮加大到手指好点的尺寸，召回标签一直露出来 */
  @media (hover: none), (pointer: coarse) {
    .waifu-tool { opacity: 1; gap: 2px; }
    .waifu-tool button { width: 40px; height: 40px; -webkit-tap-highlight-color: transparent; }
    .waifu-tool svg { width: 26px; height: 26px; }
    /* 手指点过后 :hover 会一直「粘」着，改成只在按下时变色 */
    .waifu-tool button:hover svg { fill: #7b8c9d; }
    .waifu-tool button:active svg { fill: #0684bd; }
    .waifu-tips { width: min(280px, 36vw); }
    .waifu-choice { min-height: 36px; padding: 4px 12px; }
    .waifu-number input { min-height: 36px; font-size: 16px; }   /* iOS 输入框字号 < 16px 聚焦时会自动放大页面 */
    .waifu-toggle.waifu-toggle-active,
    .waifu-toggle.waifu-toggle-active:hover { margin-right: -20px; }
  }

  /* === 首访音乐询问：原生 dialog 位于顶层，未同意时音乐资源保持未加载 === */
  .play-ask {
    position: fixed;
    inset: 0;
    margin: auto;
    padding: 0;
    width: min(380px, calc(100vw - 32px));
    max-width: calc(100vw - 32px);
    max-height: calc(100vh - 32px);
    max-height: calc(100dvh - 32px);
    border: 0;
    border-radius: 22px;
    color: var(--text);
    background: transparent;
    font: inherit;
    overflow: auto;
  }
  .play-ask::backdrop {
    background: rgba(8, 9, 20, 0.53);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
  }
  .play-ask-card {
    padding: 26px 22px 22px;
    text-align: center;
    border: 1px solid rgba(255,255,255,0.14);
    border-radius: 22px;
    background: linear-gradient(180deg, rgba(25,27,44,0.94), rgba(14,16,29,0.97));
    box-shadow: 0 22px 64px rgba(0,0,0,0.48);
  }
  [data-theme="light"] .play-ask-card {
    background: linear-gradient(180deg, #fff, #fdf5fa);
    border-color: rgba(255,255,255,0.95);
    box-shadow: 0 22px 64px rgba(40,25,55,0.24);
  }
  .play-ask-icon { font-size: 32px; line-height: 1; margin-bottom: 12px; }
  .play-ask-title { font-size: 18px; color: var(--card-name); margin-bottom: 8px; }
  .play-ask-desc { font-size: 13px; line-height: 1.7; color: var(--text-muted); margin-bottom: 20px; }
  .play-ask-btns { display: flex; gap: 10px; }
  .play-ask-btn {
    flex: 1;
    min-height: 44px;
    padding: 10px 14px;
    border: 1px solid var(--btn-border);
    border-radius: 12px;
    font: inherit;
    font-size: 14px;
    color: var(--text);
    background: var(--btn-bg);
    cursor: pointer;
  }
  .play-ask-btn:hover { background: var(--card-hover); }
  .play-ask-btn.primary {
    color: #fff;
    background: #be185d;
    border-color: #be185d;
  }
  .play-ask-btn.primary:hover { background: #9d174d; }
  [data-theme="light"] .play-ask-btn.primary { background: #be185d; }
  @media (max-width: 420px) {
    .play-ask-card { padding: 22px 18px 18px; }
  }

  /* === 手机端播放器：默认收在左下角一个小按钮里，点开才展开（免得挡住页脚） ===
     展开时占满底部（左边给小按钮让位），底部控件组由 JS 实时抬到它上方 */
  .music-toggle { display: none; }
  /* 收起状态下音乐还在放：按钮轻轻呼吸，免得以为没在响。
     只动阴影不动 transform —— 桌面端手柄的 transform 要留给抽屉位移，不能被动画抢走 */
  @keyframes musicBreath {
    0%, 100% { box-shadow: inset 0 1px 0 rgba(255,255,255,0.16), 0 4px 16px var(--shadow); }
    50%      { box-shadow: inset 0 1px 0 rgba(255,255,255,0.16), 0 6px 22px var(--accent2); }
  }

  @media (max-width: 640px) {
    .music-toggle {
      display: flex;
      align-items: center;
      justify-content: center;
      position: fixed;
      left: 10px;
      bottom: calc(10px + env(safe-area-inset-bottom, 0px));
      z-index: 11;                     /* 盖在播放器(10)上面 */
      width: 44px;
      height: 44px;
      padding: 0;
      font-size: 19px;
      line-height: 1;
      color: var(--btn-text);
      background: var(--btn-bg);
      border: 1px solid var(--btn-border);
      border-radius: 14px;
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
      box-shadow: 0 4px 16px var(--shadow);
      cursor: pointer;
      touch-action: none;              /* 手机上拖按钮别连带滚页面 */
      user-select: none;
      -webkit-user-select: none;
      transition: transform 0.2s ease, background 0.2s ease;
    }
    .music-toggle:active { transform: scale(0.92); }
    .music-toggle.is-dragging { transform: scale(1.08); }
    /* 拖到屏幕边上：缩小、贴着边站（缩小方向由 JS 设的 transform-origin 决定） */
    .music-toggle.is-docked { transform: scale(0.78); }
    .music-toggle.is-playing { animation: musicBreath 1.8s ease-in-out infinite; }

    .music-player {
      left: 62px;                      /* 给左下角的小按钮让位 */
      right: 10px;
      bottom: calc(10px + env(safe-area-inset-bottom, 0px));
      width: auto;
      transition: transform 0.34s cubic-bezier(.4, 0, .2, 1), opacity 0.26s ease;
    }
    /* 按钮被拖到屏幕右半边时，播放器也跟着贴右边 */
    .music-player.is-right { left: 10px; right: 62px; }
    /* 收回：整块滑到屏幕外面，但保留布局尺寸（APlayer 内部量到 0 尺寸会乱） */
    .music-player.is-collapsed {
      transform: translateX(calc(-100% - 80px));
      opacity: 0;
      pointer-events: none;
    }
    .music-player.is-collapsed.is-right { transform: translateX(calc(100% + 80px)); }
    .fixed-bottom { right: 12px; }
  }

  /* === 桌面端播放器：抽屉。左边一个小手柄，点开滑出，闲置自动收回贴边 ===
     收起样式挂在 .is-drawer 上（JS 只在桌面端加），这样手机上不会互相干扰 */
  @media (min-width: 641px) {
    .music-toggle {
      display: flex;
      align-items: center;
      justify-content: center;
      position: fixed;
      left: 0;
      bottom: 20px;                     /* 与播放器底边对齐 */
      z-index: 11;                      /* 盖在播放器(10)上面 */
      width: 30px;
      height: 131px;                    /* 与播放器同高，JS 会按播放器实际高度再对齐一次 */
      padding: 0;
      font-size: 20px;
      line-height: 1;
      color: var(--btn-text);
      background: var(--btn-bg);
      border: 1px solid var(--btn-border);
      border-left: none;
      border-radius: 0 12px 12px 0;
      backdrop-filter: blur(10px);
      -webkit-backdrop-filter: blur(10px);
      box-shadow: inset 0 1px 0 rgba(255,255,255,0.16), 0 4px 16px var(--shadow);
      cursor: pointer;
      /* 和播放器同一时长/缓动：拉开时手柄像是被抽屉一起推出去的 */
      transition: transform 0.34s cubic-bezier(.4,0,.2,1), background 0.2s ease, color 0.2s ease;
    }
    .music-toggle:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
    .music-toggle.is-playing { animation: musicBreath 1.8s ease-in-out infinite; }
    /* 抽屉拉开：手柄跟着滑到播放器右边（距离 = 播放器 left 36 + 宽 300）。
       贴上去之后不再需要自己的外阴影，只留顶部内高光，跟播放器拼成一块 */
    .music-toggle.is-drawer-open {
      transform: translateX(336px);
      box-shadow: inset 0 1px 0 rgba(255,255,255,0.16);
    }

    .music-player {
      left: 36px;
      width: 300px;                     /* 能收起来了，宽度加 20px */
      transition: transform 0.34s cubic-bezier(.4,0,.2,1);   /* 与手柄同步 */
    }
    /* 拉开时手柄和播放器拼成一整块：播放器右侧改直角、去掉自己的右边框，
       否则播放器的圆角 + 手柄的方边之间会露出一道接缝，看着像两个控件 */
    .music-player.is-drawer { border-radius: 12px 0 0 12px; border-right: none; }
    /* 收起：右边缘正好停在屏幕左边缘，手柄留在外面。
       这里不能用 opacity —— 手柄是跟着一起淡掉就白做了 */
    .music-player.is-drawer.is-collapsed {
      transform: translateX(calc(-100% - 36px));
      pointer-events: none;
    }
  }
