/*
 * 0.4 基础组件：列表行、mini player、sheet、分组设置，外加按钮、chip、开关、菜单、轻提示、空状态、骨架屏。
 * 和 App 的 lib/src/ui/components.dart 同一套样子；只引用 tokens.css 里的变量，禁止硬编码色值。
 */

/* ---------------- 按钮 ---------------- */

/* 文字按钮：绿色文字（--tint 当文字够 4.5:1），热区 ≥44 */
.ui-btn {
  min-width: var(--touch);
  min-height: var(--touch);
  display: inline-grid;
  place-items: center;
  padding: 0 var(--sp-8);
  border: 0;
  border-radius: var(--r-btn);
  background: transparent;
  color: var(--tint);
  font: var(--w-body) var(--t-body) / var(--lh-body) var(--font);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity var(--d-icon) var(--ease-out), background-color var(--d-icon) var(--ease-out);
}
.ui-btn:active { opacity: 0.5; }
.ui-btn:focus-visible, .row:focus-visible, .cell:focus-visible, .menu-item:focus-visible, .card:focus-visible, .quick:focus-visible { outline: 2px solid var(--tint); outline-offset: -2px; }
.ui-btn[disabled] { color: var(--label-3); cursor: default; opacity: 1; }
.ui-btn.strong { font-weight: var(--w-headline); }
.ui-btn.danger { color: var(--danger); }
.ui-btn svg { width: 22px; height: 22px; }
.ui-btn.icon { padding: 0; color: var(--label); border-radius: 50%; }
.ui-btn.icon.muted { color: var(--label-2); }

/* 主按钮：胶囊、品牌绿底、近黑字（白字在品牌绿上不够 4.5:1） */
.ui-btn.primary {
  min-height: var(--btn-h);
  padding: 0 var(--sp-24);
  background: var(--brand);
  color: var(--on-brand);
  font-weight: var(--w-headline);
}
.ui-btn.primary[disabled] { background: var(--fill); color: var(--label-3); }

/* chip：胶囊（搜索历史、音质、版本切换）。看着 32 高，点的范围上下补到 44 */
.chip {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 var(--sp-12);
  border: 0;
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--label);
  font: var(--w-sub) var(--t-sub) / var(--lh-sub) var(--font);
}
button.chip { cursor: pointer; -webkit-tap-highlight-color: transparent; }
button.chip::after { content: ''; position: absolute; inset: -6px 0; }
.chip[aria-pressed="true"], .chip.on { background: var(--brand); color: var(--on-brand); }
/* 小标签（音质）：描边小字 */
.badge { flex: none; display: inline-block; padding: 0 3px; border: 0.8px solid currentColor; border-radius: 3px; font: 700 9px / 1.35 var(--font); }
.badge.sq { color: var(--sq); }

/* ---------------- 列表行 ---------------- */
/*
 * 48 封面（或序号）| 歌名（15）+ SQ / 已缓存 / 歌手 · 专辑（12）| 版本、时长、⋮
 * 64 高，不画分割线。正在放：歌名绿色加粗；有序号的列表里序号换成跳动的小竖条
 */

.list { display: flex; flex-direction: column; }

.row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--row-gap);
  min-height: var(--row-h);
  padding: 0 var(--sp-4) 0 var(--margin);
  color: var(--label);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color var(--d-icon) var(--ease-out);
}
.row:active { background: var(--fill); }
@media (hover: hover) { .row:hover { background: var(--fill); } }

.row-art {
  flex: none;
  width: var(--row-art);
  height: var(--row-art);
  border-radius: var(--r-art);
  overflow: hidden;
  background: var(--surface-2);
  display: grid;
  place-items: center;
  color: var(--label-3);
}
.row-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.row-art svg { width: 20px; height: 20px; }

.row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.row-title {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  font: var(--w-body) var(--t-body) / var(--lh-body) var(--font);
  white-space: nowrap;
  overflow: hidden;
}
.row-title .txt { overflow: hidden; text-overflow: ellipsis; }
.row-sub {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  min-width: 0;
  font: var(--w-foot) var(--t-foot) / var(--lh-foot) var(--font);
  color: var(--label-2);
  white-space: nowrap;
}
.row-sub .txt { overflow: hidden; text-overflow: ellipsis; }
.row-trail { flex: none; display: flex; align-items: center; color: var(--label-2); }
.row-dur { padding-left: var(--sp-8); font: var(--w-foot) var(--t-foot) / var(--lh-foot) var(--font); color: var(--label-2); font-variant-numeric: tabular-nums; }

.row.is-playing .row-title { color: var(--tint); font-weight: var(--w-headline); }

/* 待同步：副标题前的小圆点（弱提示，不阻塞操作） */
.sync-dot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--warning); }

/* 多版本：行尾「N 个版本」，点开切换 */
.row-versions { min-height: var(--touch); padding: 0 var(--sp-8); border: 0; background: transparent; color: var(--tint); font: var(--w-foot) var(--t-foot) / 1 var(--font); cursor: pointer; }

/* 无封面的行、带序号的行（歌单 / 专辑） */
.row-plain { min-height: var(--cell-h); }
.row-index { flex: none; width: 32px; display: grid; place-items: center; color: var(--label-2); font: 600 var(--t-body) / 1 var(--font); font-variant-numeric: tabular-nums; }
.row-index.top { color: var(--tint); }

/* 正在放的跳动小竖条（减少动态效果时不动） */
.bars { display: inline-flex; align-items: flex-end; gap: 2px; width: 14px; height: 14px; color: var(--tint); }
.bars i { flex: 1; height: 40%; border-radius: 1px; background: currentColor; }
.bars.on i { animation: bar 0.9s ease-in-out infinite; }
.bars.on i:nth-child(2) { animation-delay: -0.3s; }
.bars.on i:nth-child(3) { animation-delay: -0.6s; }
@keyframes bar { 0%, 100% { height: 30%; } 50% { height: 100%; } }
@media (prefers-reduced-motion: reduce) { .bars.on i { animation: none; } .bars i:nth-child(1) { height: 60%; } .bars i:nth-child(2) { height: 100%; } }

.row.is-new { animation: row-in var(--d-insert) var(--ease) both; }
@keyframes row-in { from { opacity: 0; transform: translateY(8px); } }

/* ---------------- 空状态 / 加载 / 出错 ---------------- */

.empty-state { display: grid; justify-items: center; gap: var(--sp-12); padding: var(--sp-34) var(--margin); text-align: center; }
.empty-state svg { width: 44px; height: 44px; color: var(--label-3); }
.empty-state p { margin: 0; max-width: 30ch; color: var(--label-2); font: var(--w-body) var(--t-body) / var(--lh-body) var(--font); }
.empty-state.error svg { color: var(--error); }

.skeleton { display: flex; flex-direction: column; }
.skeleton .sk-row { display: flex; align-items: center; gap: var(--row-gap); min-height: var(--row-h); padding: 0 var(--margin); }
.skeleton .sk-art { flex: none; width: var(--row-art); height: var(--row-art); border-radius: var(--r-art); background: var(--surface-2); }
.skeleton .sk-lines { flex: 1; display: grid; gap: var(--sp-8); }
.skeleton .sk-line { height: 12px; border-radius: var(--r-pill); background: var(--surface-2); }
.skeleton .sk-line.short { width: 45%; }
.skeleton .sk-line.long { width: 70%; }
.skeleton { animation: sk-pulse 1.4s ease-in-out infinite; }
@keyframes sk-pulse { 50% { opacity: 0.55; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

.spinner { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--fill); border-top-color: var(--label-2); animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .spinner { animation-duration: 2.4s; } }

/* ---------------- mini player ---------------- */
/*
 * 胶囊：播放时慢慢转的圆形封面、「歌名 - 歌手」一行、外圈是进度环的播放键、播放列表。
 * data-state：playing / paused / buffering / retrying / error —— 只展示状态，从不展示播放地址
 */

.mini {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-8);
  height: var(--mini-h);
  padding: 0 var(--sp-4) 0 6px;
  border-radius: var(--r-mini);
  background: var(--surface);
  box-shadow: var(--shadow-float);
  color: var(--label);
  overflow: hidden;
}
.mini-open { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--sp-12); min-height: var(--touch); padding: 0; border: 0; background: transparent; color: inherit; text-align: left; cursor: pointer; }
/* 圆形封面：黑胶一样的深色外圈，播放时 20 秒转一圈 */
.mini .disc { flex: none; width: var(--mini-art); height: var(--mini-art); padding: 4px; box-sizing: border-box; border-radius: 50%; background: var(--disc); animation: disc 20s linear infinite; animation-play-state: paused; }
.mini[data-state="playing"] .disc { animation-play-state: running; }
.mini .disc .row-art { width: 100%; height: 100%; border-radius: 50%; }
@keyframes disc { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .mini .disc { animation: none; } }
.mini-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.mini-title { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font: var(--w-body) var(--t-body) / var(--lh-body) var(--font); }
.mini-title .by { color: var(--label-2); }
.mini-sub { display: block; font: var(--w-foot) var(--t-foot) / var(--lh-foot) var(--font); color: var(--label-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mini-sub:empty { display: none; }
.mini[data-state="error"] .mini-sub { color: var(--danger); }
.mini-ctrl { flex: none; display: flex; align-items: center; }
.mini-ctrl .ui-btn { color: var(--label); }
.mini-ctrl .ui-btn svg { width: 24px; height: 24px; }
.mini .ui-btn.text { font: var(--w-headline) var(--t-sub) / 1 var(--font); color: var(--tint); }
/* 播放键：34 的圆，外圈是进度环（热区 44） */
.mini .ring { position: relative; display: grid; place-items: center; width: 34px; height: 34px; }
.mini .ring svg.prog { position: absolute; inset: 0; width: 34px; height: 34px; transform: rotate(-90deg); }
.mini .ring .track { stroke: var(--separator); }
.mini .ring .done { stroke: var(--brand); transition: stroke-dashoffset 0.5s linear; }
.mini .ring .glyph { width: 16px; height: 16px; }
/* 上面 .mini-ctrl .ui-btn svg 会把所有图标设成 24px，这里的图标要跟着 16px 的框走，否则往右下偏 4px（0.5.9） */
.mini .ring .glyph svg { display: block; width: 100%; height: 100%; }
.mini .ring .play, .mini .ring .busy { grid-area: 1 / 1; display: grid; place-items: center; transition: opacity var(--d-icon) var(--ease-out); }
.mini .ring .spinner { width: 14px; height: 14px; }
.mini .busy { opacity: 0; pointer-events: none; }
.mini[data-state="buffering"] .busy, .mini[data-state="retrying"] .busy { opacity: 1; }
.mini[data-state="buffering"] .play, .mini[data-state="retrying"] .play { opacity: 0; }

/* ---------------- sheet ---------------- */

.sheet-scrim { position: fixed; inset: 0; z-index: var(--z-scrim); background: var(--scrim); opacity: 0; transition: opacity var(--d) var(--ease); }
.sheet-scrim.open { opacity: 1; }

.sheet {
  position: fixed;
  z-index: var(--z-sheet);
  left: 0;
  right: 0;
  bottom: 0;
  max-height: calc(100% - 48px - env(safe-area-inset-top, 0px));
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  box-shadow: var(--shadow-float);
  color: var(--label);
  transform: translateY(100%);
  transition: transform var(--d) var(--ease);
  outline: none;
}
.sheet.open { transform: translateY(0); }
.sheet.dragging { transition: none; }
.sheet.grouped { background: var(--bg-grouped); }

.sheet-grabber { flex: none; display: grid; place-items: center; height: 20px; cursor: grab; touch-action: none; }
.sheet-grabber::before { content: ""; width: 36px; height: 4px; border-radius: 2px; background: var(--label-3); }

.sheet-head { flex: none; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; min-height: var(--touch); padding: 0 var(--sp-8); touch-action: none; }
.sheet-head h2 { margin: 0; font: var(--w-headline) var(--t-headline) / var(--lh-headline) var(--font); text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sheet-head .l { justify-self: start; }
.sheet-head .r { justify-self: end; }

.sheet-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-bottom: calc(var(--sp-16) + env(safe-area-inset-bottom, 0px)); }

@media (min-width: 768px) {
  .sheet {
    left: 50%;
    right: auto;
    top: 50%;
    bottom: auto;
    width: min(540px, calc(100% - 48px));
    max-height: min(720px, calc(100% - 96px));
    border-radius: var(--r-sheet);
    transform: translate(-50%, calc(-50% + 24px));
    opacity: 0;
    transition: transform var(--d) var(--ease), opacity var(--d) var(--ease);
  }
  .sheet.open { transform: translate(-50%, -50%); opacity: 1; }
  .sheet-grabber { display: none; }
}

/* ---------------- 分组设置 ---------------- */
/* 白卡片圆角 16，组标题是 16 粗的正文色；行 52 高、行间细线 */

.grouped { background: var(--bg-grouped); color: var(--label); padding-block: var(--sp-8) var(--sp-34); }
.group { margin: 0 var(--margin) var(--group-gap); }
.group-header { margin: 0 var(--sp-4) var(--sp-8); color: var(--label); font: var(--w-headline) var(--t-headline) / var(--lh-headline) var(--font); }
.group-body { border-radius: var(--r-card); background: var(--surface); overflow: hidden; }
.group-footer { margin: 6px var(--sp-4) 0; color: var(--label-2); font: var(--w-foot) var(--t-foot) / var(--lh-foot) var(--font); }

.grouped.two-col { display: grid; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1024px) {
  .grouped.two-col { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--sp-20); padding-inline: var(--margin); }
  .grouped.two-col .group { margin-inline: 0; }
}

.cell {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-12);
  width: 100%;
  min-height: var(--cell-h);
  padding: var(--sp-8) var(--margin);
  box-sizing: border-box;
  border: 0;
  background: transparent;
  color: var(--label);
  font: var(--w-body) var(--t-body) / var(--lh-body) var(--font);
  text-align: left;
}
button.cell, a.cell, .cell[role="button"] { cursor: pointer; -webkit-tap-highlight-color: transparent; }
a.cell { color: inherit; text-decoration: none; }
button.cell:active, a.cell:active, .cell[role="button"]:active { background: var(--fill); }
@media (hover: hover) { button.cell:hover { background: var(--fill); } }
.cell::after { content: ""; position: absolute; left: var(--margin); right: 0; bottom: 0; height: 1px; background: var(--separator); }
.cell:last-child::after { display: none; }
.cell .label { flex: 1; min-width: 0; }
.cell .label small { display: block; color: var(--label-2); font: var(--w-foot) var(--t-foot) / var(--lh-foot) var(--font); }
.cell .value { color: var(--label-2); text-align: right; font: var(--w-sub) var(--t-sub) / var(--lh-sub) var(--font); font-variant-numeric: tabular-nums; }
.cell .chev { flex: none; width: 8px; height: 13px; color: var(--label-3); }
.cell .check { flex: none; width: 18px; height: 18px; color: var(--tint); visibility: hidden; }
.cell[aria-checked="true"] .check { visibility: visible; }
.cell.center { justify-content: center; color: var(--tint); }
.cell.center .label { flex: none; }
.cell.danger { color: var(--danger); }
/* 左边的线性小图标（原型是单色图标，不再是彩色方块） */
.cell .ico { flex: none; width: 22px; height: 22px; display: grid; place-items: center; color: var(--label-2); background: none !important; }
.cell .ico svg { width: 22px; height: 22px; }
.cell:has(.ico)::after { left: calc(var(--margin) + 22px + var(--sp-12)); }

.cell input:not(.switch), .cell textarea { flex: 2; min-width: 0; border: 0; background: transparent; color: var(--label); font: inherit; text-align: right; outline: none; }
.cell input:not(.switch)::placeholder, .cell textarea::placeholder { color: var(--label-3); }
.cell.stacked { flex-direction: column; align-items: stretch; gap: var(--sp-4); }
.cell.stacked textarea { text-align: left; min-height: 120px; resize: vertical; font: var(--w-sub) var(--t-sub) / var(--lh-sub) var(--font); }

/* 开关：打开是品牌绿、白圆钮 */
.switch { position: relative; flex: none; width: 52px; height: 32px; margin: 6px 0; appearance: none; -webkit-appearance: none; border-radius: var(--r-pill); background: var(--fill); cursor: pointer; transition: background-color var(--d) var(--ease); }
.switch::before { content: ""; position: absolute; top: 3px; left: 3px; width: 26px; height: 26px; border-radius: 50%; background: var(--knob); box-shadow: var(--knob-shadow); transition: transform var(--d) var(--ease); }
.switch:checked { background: var(--brand); }
.switch:checked::before { transform: translateX(20px); }
.switch:focus-visible { outline: 2px solid var(--tint); outline-offset: 2px; }

/* ---------------- 上下文菜单（⋮） ---------------- */

.menu {
  position: fixed;
  z-index: var(--z-menu);
  min-width: 220px;
  max-width: min(280px, calc(100vw - 2 * var(--margin)));
  padding: var(--sp-4) 0;
  border-radius: var(--r-menu);
  background: var(--surface);
  box-shadow: var(--shadow-float);
  overflow: hidden;
  transform-origin: top right;
  animation: menu-in var(--d) var(--ease) both;
}
@keyframes menu-in { from { opacity: 0; transform: scale(0.94); } }
.menu-item { position: relative; display: flex; align-items: center; gap: var(--sp-12); width: 100%; min-height: 48px; padding: 0 var(--sp-16); border: 0; background: transparent; color: var(--label); font: var(--w-body) var(--t-body) / var(--lh-body) var(--font); text-align: left; cursor: pointer; }
.menu-item span { flex: 1; }
.menu-item:active, .menu-item:hover { background: var(--fill); }
.menu-item svg { flex: none; order: -1; width: 20px; height: 20px; color: var(--label-2); }
.menu-item.danger { color: var(--danger); }
.menu-item.danger svg { color: var(--error); }
.menu-catch { position: fixed; inset: 0; z-index: calc(var(--z-menu) - 1); }

/* ---------------- 轻提示 ---------------- */
/* 反色胶囊：深色字底（浅色主题下是近黑底白字），2 秒自动消失 */

#ui-toast {
  position: fixed;
  z-index: var(--z-toast);
  left: 50%;
  top: calc(var(--sp-12) + env(safe-area-inset-top, 0px));
  width: max-content;
  max-width: calc(100% - 2 * var(--margin));
  padding: var(--sp-8) var(--sp-16);
  border-radius: var(--r-pill);
  background: var(--label);
  box-shadow: var(--shadow-float);
  color: var(--bg);
  font: var(--w-headline) var(--t-sub) / var(--lh-sub) var(--font);
  transform: translate(-50%, -16px);
  opacity: 0;
  pointer-events: none;
  transition: transform var(--d) var(--ease), opacity var(--d) var(--ease);
}
#ui-toast.show { transform: translate(-50%, 0); opacity: 1; }

/* ---------------- 分段控件（管理页还在用） ---------------- */

.seg-ctl { display: flex; gap: 2px; padding: 2px; border-radius: 10px; background: var(--fill); }
.seg-ctl button { position: relative; flex: 1; min-height: 32px; padding: 0 var(--sp-12); border: 0; border-radius: 8px; background: transparent; color: var(--label); font: var(--w-headline) var(--t-foot) / 1 var(--font); cursor: pointer; transition: background-color var(--d-tab) var(--ease-out); }
.seg-ctl button[aria-selected="true"] { background: var(--seg-thumb); box-shadow: var(--shadow-thumb); }
.seg-ctl button:focus-visible { outline: 2px solid var(--tint); outline-offset: -2px; }
.seg-ctl button::after { content: ''; position: absolute; inset: -6px 0; }

/* ---------------- 下划线标签（音乐库 歌曲 / 专辑 / 歌手 / 歌单） ---------------- */

.tabs { display: flex; gap: var(--sp-4); }
.tabs button { position: relative; display: grid; justify-items: center; align-content: center; gap: 4px; min-width: 56px; min-height: var(--touch); padding: 0 var(--sp-8); border: 0; background: transparent; color: var(--label-2); font: var(--w-body) var(--t-headline) / var(--lh-headline) var(--font); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.tabs button::after { content: ''; width: 0; height: 3px; border-radius: 2px; background: var(--brand); transition: width var(--d-tab) var(--ease-out); }
.tabs button[aria-selected="true"] { color: var(--label); font-weight: 700; }
.tabs button[aria-selected="true"]::after { width: 18px; }
.tabs button:focus-visible { outline: 2px solid var(--tint); outline-offset: -2px; border-radius: var(--r-art); }

/* ---------------- 搜索框：胶囊 ---------------- */

.search-field {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: var(--touch);
  padding: 0 var(--sp-8) 0 14px;
  border-radius: var(--r-field);
  background: var(--surface);
  color: var(--label-3);
  box-sizing: border-box;
}
.search-field svg { flex: none; width: 20px; height: 20px; }
.search-field input { flex: 1; min-width: 0; border: 0; background: transparent; color: var(--label); font: var(--w-sub) var(--t-sub) / var(--lh-sub) var(--font); outline: none; }
.search-field input::placeholder { color: var(--label-2); }
.search-field input::-webkit-search-cancel-button { display: none; }
.search-field .clear { position: relative; display: grid; place-items: center; width: 28px; height: 28px; border: 0; border-radius: 50%; background: transparent; color: var(--label-3); cursor: pointer; padding: 0; }
.search-field .clear svg { width: 18px; height: 18px; }
.search-field .clear::after { content: ''; position: absolute; inset: -8px; }

/* 分组里「左边整块可点 + 右边一个按钮」的一格（切换版本里的「不是同一首」） */
.cell .cell-main { flex: 1; min-width: 0; display: flex; align-items: center; min-height: var(--touch); padding: 0; border: 0; background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.cell:has(.cell-main) { padding-right: var(--sp-4); }
