/* ============================================================
 * Longlight - 长光雨滴小站 | 公共控件：悬浮播放组件 components/mini-player.css
 * 来源：~README/项目架构.js → 风格（空气投影 / 全息屏 / 圆角 / 间隔 / 动效）
 * 用法：CUI 终端与全部 GUI 页面共用，由 shared/miniPlayer.js 注入 DOM（FE-08）；
 *       两套变体只靠 [data-variant="gui|cui"] 区分，逻辑与 DOM 完全共享（FE-06）；
 *       视觉已统一：基座即两变体共用的唯一样式，cui 只改停靠位置（抬到终端输入行上方）；
 *       全息屏与悬浮条的上下方位由 [data-screen-pos="top|bottom"] 控制（默认 top，见文末）
 * 视觉：空气投影——仅描边与字色，无实心底、无投影、无立体感；颜色一律取 tokens.css 令牌
 *       唯一例外是封面：封面作黑胶唱片处理（中心标 + 厚实盘体与同心沟槽，见 .mini-cover::after），
 *       盘体取唱片实物的中性深色而非主题令牌——唱片是实物，不该随投影底色翻转
 * ============================================================ */

/* ========== 基座（两变体共用；停靠右下、全息屏向上展开；cui 见文末仅改停靠位置） ========== */
.mini-player {
  position: fixed;
  /* 低于 home 点火层（z-index 8）：点火仪式期间被整层覆盖，不干扰入场 */
  z-index: 7;
  bottom: var(--space-card);
  right: var(--space-page-desktop);
  display: none;
  align-items: center;
  gap: var(--space-icon-text);
  box-sizing: border-box;
  width: 300px;
  padding: 10px 12px;
  border: var(--border-soft);
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--bg) 55%, transparent);
  font: var(--text-ui);
  color: var(--text-secondary);
  cursor: grab;
  -webkit-user-select: none;
  user-select: none;
  transition: border-color var(--duration-hover) var(--ease-out);
}

.mini-player.is-on { display: flex; }
.mini-player.is-dragging { cursor: grabbing; }
.mini-player:hover { border-color: var(--green-700); }

.mini-cover {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border: var(--border-soft);
  border-radius: var(--radius-circle);
  overflow: hidden;
  /* 封面旋转由 JS 以 currentTime 驱动（见 miniPlayer.js 的 startDisc），此处声明 GPU 合成提示 */
  will-change: transform;
  /* 黑胶取唱片实体的中性深色：唱片是实物，不随投影底色翻转
     （局部质感变量不覆盖 tokens.css 的设计令牌，同类做法见 pages/access 的 --mk-*） */
  --vinyl-body: #14100E;
}

/* 黑胶外圈：封面画即唱片中心标（label），四周包一圈厚实的盘体与同心沟槽。
   盘面通体为旋转对称的同心纹路（旋转不产生错位），故整块随封面一同转动；
   ::after 定位在 .mini-cover 的填充盒上，中心以 mask 透空露出封面画 */
.mini-cover::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--radius-circle);
  pointer-events: none;
  background:
    /* 盘缘斜面高光：外沿受光，撑出盘体厚度 */
    radial-gradient(circle closest-side at 50% 50%,
      transparent 0 90%, rgba(255, 255, 255, .16) 91% 96%, transparent 97% 100%),
    /* 中心标外沿一圈弱反光：提示盘面在此收口 */
    radial-gradient(circle closest-side at 50% 50%,
      transparent 0 66%, rgba(255, 255, 255, .12) 67% 70%, transparent 71% 100%),
    /* 同心沟槽：极低对比的细密重复环，远看即黑胶的哑光纹理 */
    repeating-radial-gradient(circle closest-side at 50% 50%,
      var(--vinyl-body) 0 1.4px,
      rgba(255, 255, 255, .055) 1.4px 2.2px,
      var(--vinyl-body) 2.2px 3.2px),
    var(--vinyl-body);
  /* 中心透空：封面画留作中心标，外层 34% 即黑胶盘体（约 7.5px 厚） */
  -webkit-mask-image: radial-gradient(circle closest-side at 50% 50%, transparent 0 66%, #000 66.5% 100%);
  mask-image: radial-gradient(circle closest-side at 50% 50%, transparent 0 66%, #000 66.5% 100%);
}

/* 封面缺失（媒体未部署）时只留空白框，不画占位图标 */
.mini-cover-disc { width: 100%; height: 100%; }
.mini-cover img { position: relative; display: block; width: 100%; height: 100%; object-fit: cover; }
.mini-cover img.is-missing,
.mini-cover img:not([src]) { display: none; }

.mini-info { flex: 1 1 auto; min-width: 0; }
.mini-title {
  margin: 0;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 进度条：统一取 CUI 终端语法——细方角轨道 + 方角滑块，配色走 --tok-* 令牌（两款变体共用） */
.mini-progress { padding: 7px 0 3px; cursor: pointer; }
.mini-progress-track { position: relative; height: 2px; border-radius: 0; background: var(--line); }
.mini-progress-fill {
  position: absolute; left: 0; top: 0; height: 100%; width: 0;
  border-radius: 0; background: var(--tok-sub1);
}
.mini-progress-thumb {
  position: absolute; top: 50%; left: 0;
  width: 7px; height: 11px; margin-left: -3.5px;
  border-radius: 0;
  background: var(--tok-keyword);
  transform: translateY(-50%);
  opacity: 0;
  /* 合成层常驻：滑块以 margin-left 作半像素偏移居中（7px 宽 → -3.5px），
     若等 opacity 过渡时才提升为合成层，栅格化会在「半像素抗锯齿」与「整像素对齐」间切换，
     悬停显隐瞬间出现 0.5px 跳变与边缘闪动 */
  will-change: opacity;
  transition: opacity var(--duration-hover) var(--ease-out);
}
.mini-progress:hover .mini-progress-thumb,
.mini-progress-thumb.is-dragging { opacity: 1; }

.mini-meta {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-icon-text);
  margin: 0; font: var(--text-caption); color: var(--text-secondary);
}
.mini-time { color: var(--tok-number); }

.mini-controls { flex: none; display: flex; align-items: center; gap: 2px; }
.mini-btn {
  display: inline-grid; place-items: center;
  width: 28px; height: 28px; padding: 0;
  border: 0; border-radius: var(--radius-btn);
  background: transparent; color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--duration-hover) var(--ease-out), border-color var(--duration-hover) var(--ease-out);
}
.mini-btn:hover { color: var(--green-900); }
.mini-btn:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.mini-btn.is-play {
  width: 34px; height: 34px;
  border: var(--border-soft); border-radius: var(--radius-circle);
  color: var(--text-primary);
}
.mini-btn.is-play:hover { border-color: var(--green-900); }

/* 播放 / 暂停图标随播放态切换 */
.mini-icon-pause { display: none; }
.mini-player.is-playing .mini-icon-play { display: none; }
.mini-player.is-playing .mini-icon-pause { display: inline; }

/* 缓冲中：播放键呼吸提示（弱网/未缓存曲目） */
.mini-player.is-buffering .mini-btn.is-play { animation: mini-buffer 1.1s ease-in-out infinite; }
@keyframes mini-buffer { 0%, 100% { opacity: .35; } 50% { opacity: .85; } }

/* 全息屏：默认向上展开（[data-screen-pos="bottom"] 翻转到条下方，见文末）——两变体一致 */
.mini-holo { display: none; } /* 未开启屏幕时隐藏；开启后常显 */
/* 屏幕是常驻部件：只要启用屏幕（has-screen）就常显，不做悬停显隐
   （空气投影没有「厚度」可以藏，悬停显隐只会让人以为屏幕不存在）；
   屏幕本身即拖动把手（pointer-events: auto），按下冒泡到 .mini-player 复用整块拖动逻辑 */
.mini-player.has-screen .mini-holo {
  display: block;
  position: absolute;
  left: 0; right: 0; bottom: calc(100% + 10px);
  pointer-events: auto;
}
.mini-holo-inner {
  position: relative;
  padding: 10px 12px;
  border: var(--border-soft);
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--bg) 64%, transparent);
  overflow: hidden;
}
/* 全息屏四角投影标记（空气投影：仅描边，无厚度） */
.mini-holo-corner { position: absolute; width: 10px; height: 10px; border: 1px solid var(--green-700); opacity: .7; }
.mini-holo-corner.is-tl { top: 5px; left: 5px; border-right: 0; border-bottom: 0; }
.mini-holo-corner.is-tr { top: 5px; right: 5px; border-left: 0; border-bottom: 0; }
.mini-holo-corner.is-bl { bottom: 5px; left: 5px; border-right: 0; border-top: 0; }
.mini-holo-corner.is-br { bottom: 5px; right: 5px; border-left: 0; border-top: 0; }
.mini-holo-head {
  display: flex; align-items: center; gap: var(--space-icon-text);
  padding-bottom: 6px; margin-bottom: 6px;
  border-bottom: var(--border-dashed);
  font: var(--text-caption); letter-spacing: var(--ls-caption); text-transform: uppercase;
  color: var(--text-secondary);
}
.mini-holo-dot { flex: none; width: 5px; height: 5px; border-radius: var(--radius-circle); background: var(--green-500); }
/* 专辑名固定在全息屏头部右端（屏幕右上角）：靠 margin-left:auto 顶到最右，
   flex 子项需 min-width:0 才会收缩，超长由 .mini-alb 的 ellipsis 裁掉 */
.mini-holo-head .mini-alb { margin-left: auto; min-width: 0; }

/* ---- 全息屏内容：屏内固定三项——专辑名（屏头右上，见 .mini-alb）、歌词、音频可视化音浪，
   音浪长度一律取自 AnalyserNode 的实测数据（非随机动画）；可视化用 C · 环隙 ---- */
.mini-viz { position: relative; }
.mini-alb {
  margin: 0;
  font: var(--text-caption);
  letter-spacing: var(--ls-caption);
  text-transform: uppercase;
  color: var(--text-secondary);
  opacity: .8;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mini-ly {
  margin: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: opacity var(--duration-enter) var(--ease-out);
}
/* 歌词加载中：占位省略号做呼吸动画，加载完成后由 JS 移除 is-loading */
.mini-ly.is-loading { animation: mini-lyrics-wait 1.2s ease-in-out infinite; }
@keyframes mini-lyrics-wait { 0%, 100% { opacity: .3; } 50% { opacity: .9; } }

/* C · 环隙：径向频谱环在左右留缺口，当前歌词居中横穿缺口；
   上下两段弧同心（同一圆心与半径），故上下严格对称——缺口边缘距歌词上下各留约 8px */
.mini-viz-c { position: relative; display: flex; align-items: center; justify-content: center; height: 132px; }
.mini-viz-c svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.mini-c-tick { stroke: var(--green-500); stroke-width: 1; vector-effect: non-scaling-stroke; }
.mini-c-text {
  position: absolute;
  /* 文本层按「组件整宽」铺开：屏幕与悬浮条同宽（left/right:0），此处再反向补齐屏内左右内边距
     （--space-input）与 1px 描边，使屏内文本的百分比宽度以组件宽度为基准 */
  left: calc(-1 * var(--space-input) - 1px);
  right: calc(-1 * var(--space-input) - 1px);
  /* 对齐环心（viewBox 0 0 128 132 的 y=66，正落容器 132px 的中线），不随容器高度走 */
  top: 66px;
  transform: translateY(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  text-align: center;
}
/* 歌词行宽度上限 = 组件宽度的 80% */
.mini-c-text .mini-ly { max-width: 80%; font: var(--text-caption); line-height: 16px; color: var(--text-primary); }

.mini-holo-foot {
  margin-top: 6px; padding-top: 6px;
  border-top: var(--border-dashed);
  font: var(--text-caption);
  font-size: 10px; /* 屏脚标识为装饰性微标：比 Caption 再小一档（同类做法见 components/stamp.css） */
  text-align: center;
  letter-spacing: var(--ls-caption); text-transform: uppercase;
  color: var(--text-secondary); opacity: .7;
}

/* ========== CUI 变体：视觉与 GUI 完全一致，只改停靠位置 ==========
   终端悬浮条停靠右下、抬到输入行上方（避让底部输入行），全息屏与 gui 一样向上展开；其余样式一律继承基座
   （方位取 bottom 时本段停靠被文末的 [data-screen-pos] 段接管） */
.mini-player[data-variant="cui"] {
  /* 停靠高度 = 输入行单行高（上下内边距 --space-input × 2 + 字高 18px + 顶边框 1px）
     + --space-form-field 的间距，使悬浮条恰好浮在输入行之上 */
  --mini-cui-dock: calc(var(--space-input) * 2 + 18px + 1px + var(--space-form-field));
  bottom: var(--mini-cui-dock);
  right: var(--space-page-mobile);
}

/* 提示符过长时输入行换成两行（见 pages/index/inputLayout.js 增删的 .wrap），停靠高度再加一行与行距；
   不支持 :has() 的浏览器会整条忽略，回落到上面的单行高度，不影响可用性 */
body:has(.input-line.wrap) .mini-player[data-variant="cui"] {
  --mini-cui-dock: calc(var(--space-input) * 2 + 18px * 2 + 6px + 1px + var(--space-form-field));
}

/* ========== 响应式 ========== */
@media (max-width: 768px) {
  .mini-player[data-variant="gui"] { bottom: var(--space-form-field); right: var(--space-page-mobile); width: min(300px, calc(100vw - 32px)); }
  .mini-player[data-variant="cui"] { right: var(--space-page-mobile); width: min(300px, calc(100vw - 24px)); }
}

/* 整条悬浮体被拉成全宽（移动端）：不展开全息屏，只留悬浮条本身 */
@media (max-width: 480px) {
  .mini-player[data-variant="gui"],
  .mini-player[data-variant="cui"] { width: calc(100vw - 16px); right: 8px; }
  .mini-player[data-variant="gui"] { bottom: 12px; }
  .mini-player.has-screen .mini-holo { display: none; }
}

/* 减少动态偏好：不做过渡与呼吸动画（无障碍） */
@media (prefers-reduced-motion: reduce) {
  .mini-player, .mini-ly, .mini-progress-thumb, .mini-btn { transition: none; }
  .mini-player.is-buffering .mini-btn.is-play,
  .mini-ly.is-loading { animation: none; }
}

/* 非播放器页（loading 过渡页等）：隐藏 UI 但保留组件与 <audio>——音频继续播放。
   须置于 .is-on 规则之后：两者同权重，靠顺序覆盖 display（见 core/swap.js 的页面交换） */
.mini-player.is-page-hidden { display: none; }

/* ========== 全息屏方位（music screen top|bottom，默认 bottom） ==========
   悬浮条与全息屏的上下关系由 [data-screen-pos] 决定，两变体同一套规则（FE-06）：
   bottom（默认）——整块翻转：条停靠上方（gui 与左上角模式切换控件同一档顶部留白，cui 让开终端头部），
   屏幕自条下方展开（这里把基座向上展开的 bottom 锚点翻到 top）；
   top——条停靠下方（gui 右下 / cui 输入行上方），屏幕自条上方展开。
   仅在全息屏真正展开的宽度档（>480px）生效：窄屏整条拉全宽且不展开屏幕（见上面的响应式），
   方位在该档无意义，停靠维持各变体默认。
   本段须置于文件末尾：bottom 改用 top 停靠，要先复位上面各变体与响应式段落设下的 bottom，
   否则上下同时锚定会把固定元素拉伸 */
@media (min-width: 481px) {
  .mini-player[data-screen-pos="bottom"] {
    bottom: auto;
    --mini-top-dock: var(--space-card); /* 顶部留白：与模式切换控件同一档（见 components/mode-switch.css） */
    top: var(--mini-top-dock);
  }
  /* cui 视图：让开终端头部（48px + 1px 底边框，见 pages/index/terminal.css），再留一个间距 */
  .mini-player[data-screen-pos="bottom"][data-variant="cui"] {
    --mini-top-dock: calc(48px + 1px + var(--space-form-field));
  }
  /* 屏幕翻转到条下方：反置基座的「向上展开」 */
  .mini-player[data-screen-pos="bottom"].has-screen .mini-holo {
    bottom: auto;
    top: calc(100% + 10px);
  }
}

/* bottom 落在窄桌面档（≤768px）：顶部留白与 gui 在该档的底部留白保持一致 */
@media (min-width: 481px) and (max-width: 768px) {
  .mini-player[data-screen-pos="bottom"] { --mini-top-dock: var(--space-form-field); }
}
