/* ===== 基础与页面缩放禁用 ===== */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body {
  margin: 0; padding: 0;
  /* iOS Safari 的 100vh 包含地址栏高度（页面会被顶出去一截）：
     用 svh（小视口高度）兜底，不支持 svh 的老系统回退 100vh，再由 JS 的 --appvh 精确修正 */
  height: 100vh;
  height: 100svh;
  height: calc(var(--appvh, 100vh));
  background: #161618;
  color: #f2f2f5;
  font-family: -apple-system, "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
  overflow: hidden;
  overscroll-behavior: none;           /* iOS 橡皮筋：整页不允许回弹 */
  -webkit-text-size-adjust: 100%;      /* iOS 横屏自动放大字号的坑 */
  text-size-adjust: 100%;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;         /* 长按不弹系统菜单（避免误触拖拽时弹出） */
}
.app { display: flex; flex-direction: column; height: 100%; min-height: 0; }

/* ===== 自适应：全站隐藏滚动条 =====
   页面本身不滚动（html/body overflow:hidden）；左栏与控制区内容超出时可滚动/触屏滑动，
   但不显示滚动条，视觉上保持"整屏自适应"。 */
* { scrollbar-width: none; -ms-overflow-style: none; }
*::-webkit-scrollbar { width: 0; height: 0; display: none; }
button {
  font-family: inherit; cursor: pointer; border: none; border-radius: 10px;
  background: #3a3a3e; color: #fff; padding: 9px 12px; font-size: 14px; transition: background .15s;
  white-space: nowrap; /* 按钮文字一律不折行 */
}
button:hover { background: #4a4a4f; }
button:active { background: #2c2c30; }
button.primary { background: #ff8c1a; color: #1a1a1a; font-weight: 600; }
button.primary:hover { background: #ffa040; }
button.danger { background: #c0392b; }
button.full { width: 100%; margin-top: 6px; }
/* 停止全部：只要有任意音频在播（含正在淡出）就显示暗绿色；全部真正停止后才复原 */
button.full.stop-active { background: #1f6b3f; color: #fff; border-color: #1f6b3f; }
button.full.stop-active:hover { background: #237a48; }
.icon-btn { background: #2c2c30; min-width: 40px; font-size: 16px; padding: 8px 10px; }
input[type="text"], input[type="number"] {
  background: #2c2c30; color: #fff; border: 1px solid #444; border-radius: 8px;
  padding: 8px 10px; font-size: 14px; width: 100%;
}
input[type="color"] { width: 28px; height: 28px; border: none; background: none; padding: 0; }

/* ===== 顶栏（精简） ===== */
.topbar {
  flex-shrink: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 7px 12px; background: #1f1f22; border-bottom: 1px solid #2c2c30;
  padding-top: 7px;                                          /* 兜底：老设备/无 safe-area 时也有基础留白 */
  padding-top: max(7px, constant(safe-area-inset-top));      /* iOS 11.0–11.2 旧语法 */
  padding-top: max(7px, env(safe-area-inset-top, 0px));      /* iOS 11.2+；带兜底值，避免整条声明失效 */
}
/* 独立（添加到主屏幕）模式下，系统状态栏会压在页面顶部：
   固定 20px 兜底把内容推到状态栏下方；env() 能取到真实插入值时优先用 env（避免多余留白）。 */
@media (display-mode: standalone) {
  .topbar { padding-top: max(20px, env(safe-area-inset-top, 20px)); }
}
.brand { font-weight: 700; font-size: 15px; color: #ff8c1a; white-space: nowrap; }
.proj-name { width: 140px; }
.top-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.top-actions button { font-size: 12px; padding: 7px 10px; }
.lock-btn { background: #2c2c30; padding: 8px 12px; font-size: 14px; }
.lock-btn.on { background: #ff8c1a; color: #1a1a1a; font-weight: 600; }
/* 顶栏按钮统一高度：锁定 / 全锁定 / 帮助(icon-btn) 三者等高，纵向居中 */
.topbar .icon-btn, .topbar .lock-btn, .topbar .full-lock-btn {
  display: inline-flex; align-items: center; justify-content: center;
  box-sizing: border-box; height: 36px;
}
/* 全锁定激活态：用醒目红色，区别于锁定(橙) */
.lock-btn.full-lock-btn.on { background: #c0392b; color: #fff; font-weight: 600; }

/* 顶栏：淡入淡出总控（一键作用于所有卡片 + 全局时长） */
.fade-master {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  background: #26262a; border: 1px solid #35353c; border-radius: 12px;
  padding: 4px 10px;
}
.fm-title { font-size: 12px; color: #aaa; font-weight: 600; white-space: nowrap; }
.fm-btn { font-size: 12px; padding: 5px 10px; border-radius: 9px; background: #3a3a3e; color: #ddd; white-space: nowrap; }
.fm-btn.on { background: #ff8c1a; color: #1a1a1a; font-weight: 700; }
.fm-btn.part { background: #6b4a1c; color: #ffd9a8; }
.fm-btn.ghost { background: #2c2c30; color: #999; }
.fm-lbl { font-size: 12px; color: #999; margin-left: 2px; white-space: nowrap; }
/* 需带 input[type="range"] 前缀提权，否则被全局 range 规则的 width:100% 覆盖 */
input[type="range"].fm-range { flex: 0 0 84px; width: 84px; }
.fm-val { font-size: 12px; color: #ff8c1a; min-width: 36px; font-variant-numeric: tabular-nums; }

/* ===== 左栏 + 主区 ===== */
.body-split { flex: 1; display: flex; min-height: 0; }
.sidebar {
  width: 304px; flex-shrink: 0; background: #1a1a1c; border-right: 1px solid #2c2c30;
  overflow-y: auto; display: flex; flex-direction: column;
  padding: 6px; gap: 6px;               /* 分块之间统一留白，视觉等距 */
}
/* 单列时每块自然高度、不参与压缩：这样 JS 量到的高度才准确，溢出判断也稳定 */
.sidebar > .s-section { flex: 0 0 auto; }

/* ---- 左栏分块：统一「卡片」样式（圆角 + 描边 + 一致内边距）----
   之前用的是整栏一条条底部分割线，两列时左右块高矮不一，看着上下交错很乱。
   改成独立卡片后，每块自带圆角与描边，列内自上而下等距排列，边界清晰。 */
.s-section {
  padding: 9px 11px;
  background: #232327; border: 1px solid #2f2f36; border-radius: 14px;
}
.s-section h3 {
  margin: 0 0 7px; font-size: 11.5px; color: #9a9aa2; font-weight: 600;
  letter-spacing: .6px; line-height: 1.2;
}
/* 紧跟标题的首行不再额外留上边距，各块的「首行基线」保持一致 */
.s-section h3 + .row, .s-section h3 + .seg, .s-section h3 + .sw-row { margin-top: 0; }

/* ---- 高度不够时由 JS 实测溢出后加 .cols-2（最多两列）----
   两列不是「网格自动排布」（那会让高矮不一的块左右互相错位、中间留大空洞），
   而是由 JS 生成两根独立的纵向堆叠列 .sb-col，各自从上往下依次排列，
   并按每块的真实高度挑选最平衡的切分点，两列高度接近、排布整齐。
   两列仍放不下时，JS 再通过 --sb 逐级缩小字体/图标/按钮/间距（见文件末尾缩放块）。 */
.sidebar.cols-2 {
  display: grid; align-content: start; align-items: stretch;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px; overflow-y: auto;
  width: 476px;
}
.sb-col {
  display: flex; flex-direction: column; gap: 6px;
  min-width: 0; align-self: stretch;   /* 拉伸到行高，配合 JS 让两列底边齐平 */
}
/* 分块默认保持自然高度；需要「补齐底部」时由 JS 按比例写入 flex-grow */
.sb-col > .s-section { flex: 0 0 auto; }
/* 「总音量」独占整行：dB 竖条 + 主音量/L/R 并排，挤在半列里会太窄 */
.sidebar.cols-2 > .s-wide { grid-column: 1 / -1; }
/* 窄屏（竖屏 iPad / 小窗）两列时把每列再收窄一点，给卡片区让位 */
@media (max-width: 900px) {
  .sidebar.cols-2 { width: 420px; }
}

.row { display: flex; align-items: center; gap: 8px; margin-top: 5px; flex-wrap: nowrap; }
/* 标签统一固定 50px（4 个汉字「切歌淡出」正好放得下）+ 不折行：
   同一栏内所有行的滑块起点、数值起点都对齐，不再参差不齐。 */
.row .lbl { width: 50px; min-width: 50px; color: #9a9aa2; font-size: 12px; flex-shrink: 0; white-space: nowrap; }
.mval { font-size: 12px; color: #ff8c1a; min-width: 38px; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.chk { display: flex; align-items: center; gap: 6px; color: #ddd; font-size: 13px; margin-top: 8px; }
/* .modal-box label 的纵向 flex 会把勾选框挤成居中小方块，这里以更高优先级改回横向 */
.modal-box label.chk { flex-direction: row; align-items: center; flex-wrap: nowrap; }
.modal-box label.chk input[type="checkbox"] { width: 15px; height: 15px; flex: 0 0 auto; margin: 0; }
.seg { display: flex; gap: 6px; }
.seg-btn { flex: 1; background: #2c2c30; color: #ddd; padding: 7px; font-size: 12px; white-space: nowrap; }
.seg-btn.active { background: #ff8c1a; color: #1a1a1a; font-weight: 700; }
.stereo { margin-top: 4px; }
.master-btns { display: flex; gap: 8px; align-items: center; margin-top: 6px; }
.master-btns .full { margin-top: 0; }

/* 总音量：左侧竖条 dB 电平表 + 横向主音量滑块 */
.master-vol-block { display: flex; gap: 14px; align-items: stretch; }
.dbmeter-wrap { display: flex; flex-direction: column; align-items: center; gap: 6px; flex-shrink: 0; }
.dbmeter {
  width: 24px; flex: 1 1 auto; min-height: 72px; border-radius: 12px; overflow: hidden;
  display: flex; align-items: flex-end;          /* 电平由底部向上增长 */
  background: #3f3f47; border: 1px solid #55555c;
}
.dbm-fill {
  width: 100%; height: 0%;
  background: linear-gradient(0deg, #27ae60 0%, #27ae60 55%, #f39c12 80%, #e74c3c 100%);
}
.dbm-val {
  font-size: 11px; color: #cfcfd4; font-variant-numeric: tabular-nums;
  min-width: 54px; text-align: center; white-space: nowrap;
}
.master-right { flex: 1; display: flex; flex-direction: column; gap: 8px; justify-content: center; }
.master-right input[type="range"] { flex: 1; min-width: 0; }
/* 主音量整块加粗加大：轨道 16px、圆钮 30px、触控行高 46px，粗手指也能稳稳触发/拖动。
   只改 --track-h / --thumb-h / height，圆钮偏移由变量自动推导，仍然精确垂直居中。 */
.master-right #masterVol {
  --track-h: calc(16px * var(--sb, 1));
  --thumb-h: calc(30px * var(--sb, 1));
  height: calc(46px * var(--sb, 1));
  /* 自定义指针处理（见 app.js）：按下轨道任意位置即可滑动调音量，\n     用 none 让原生 range 不再抢水平手势。 */
  touch-action: none;
}
.master-right #masterVol::-webkit-slider-thumb { border-width: 3px; }
.master-right #masterVol::-moz-range-thumb { border-width: 3px; }
/* L / R 声道跟着适度加粗，和主音量视觉保持同一档 */
.master-right .stereo input[type="range"] {
  --track-h: calc(12px * var(--sb, 1));
  --thumb-h: calc(24px * var(--sb, 1));
  height: calc(38px * var(--sb, 1));
}
/* 用 id 选择器：保证不被后面 .sidebar .mval 的同权重规则盖掉 */
.master-right #masterVolVal {
  color: #ff8c1a; font-weight: 700; font-variant-numeric: tabular-nums;
  font-size: calc(15px * var(--sb, 1)); min-width: calc(50px * var(--sb, 1)); text-align: right;
}
/* 静音按钮加大，触控更稳（同样用 id 提权） */
.master-btns #masterMute { min-width: calc(46px * var(--sb, 1)); font-size: calc(18px * var(--sb, 1)); }

/* 滑动开关（循环播放 / 切歌交叉淡变） */
.sw-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.sw-label { font-size: 13px; color: #ddd; white-space: nowrap; min-width: 0; }
.switch { position: relative; display: inline-block; width: 46px; height: 26px; flex-shrink: 0; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.sw-slider {
  position: absolute; inset: 0; background: #4a4a4f; border-radius: 26px;
  cursor: pointer; transition: background .22s ease;
}
.sw-slider::before {
  content: ''; position: absolute; left: 3px; top: 3px; width: 20px; height: 20px;
  background: #fff; border-radius: 50%; transition: transform .22s ease;
  box-shadow: 0 1px 3px rgba(0,0,0,.45);
}
.switch input:checked + .sw-slider { background: #ff8c1a; }
.switch input:checked + .sw-slider::before { transform: translateX(20px); }
.switch input:focus-visible + .sw-slider { outline: 2px solid #ff8c1a; outline-offset: 2px; }

/* 分组分页 */
.group-pager { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; }
.group-pager .icon-btn { min-width: 34px; }
.page-info { font-size: 12px; color: #999; flex: 1; text-align: center; white-space: nowrap; }

/* 正在播放（顶栏右侧：固定宽度小胶囊，名字过长在胶囊内滚动，宽度永不变化） */
.np-bar {
  margin-left: auto; display: flex; align-items: center; gap: 8px;
  /* 固定宽度：不随歌名长短变化，长名字在内部滚动 */
  flex: 0 0 auto; width: 240px; min-width: 240px; max-width: 240px;
  padding: 3px 10px; border-radius: 12px; background: #26262a; border: 1px solid #35353c;
  overflow: hidden;
}
.np-cap { font-size: 12px; color: #999; white-space: nowrap; flex-shrink: 0; }
.np-bar .np-list {
  display: flex; flex-wrap: nowrap; align-items: center; gap: 6px;
  flex: 1; min-width: 0; overflow-x: auto; overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
}
.np-none { color: #666; font-size: 12px; white-space: nowrap; }
.np-chip {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; background: #ff3b30; color: #fff;
  border-radius: 20px; padding: 3px 10px; font-weight: 600; font-size: 12px; animation: pulse 1.2s infinite;
}
/* 名字过长：胶囊内部横向滚动（宽度不变），单个歌名最多 12 字省略 */
.np-chip .np-name {
  display: inline-block; max-width: 9.5em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .6; } }

/* 时钟 / 计时（字号随视口高度自适应，保证整屏放得下） */
.clock { font-size: clamp(22px, 3.6vh, 36px); line-height: 1.15; font-weight: 700; color: #ff8c1a; font-variant-numeric: tabular-nums; letter-spacing: 1px; }
.timer { font-size: clamp(16px, 2.6vh, 28px); color: #f2f2f5; font-variant-numeric: tabular-nums; flex: 1; text-align: right; font-weight: 600; }

/* 分组标签 */
.group-tabs { display: flex; flex-direction: column; gap: 4px; }
.group-tab {
  display: flex; align-items: center; justify-content: space-between; gap: 6px;
  background: #2c2c30; color: #ddd; padding: 6px 10px; border-radius: 10px; font-size: 12px;
}
.group-tab.active { background: #ff8c1a; color: #1a1a1a; font-weight: 600; }
.group-tab.ghost { background: transparent; border: 1px dashed #33333a; color: #4a4a4f; pointer-events: none; }
.group-tab.ghost > span { text-align: center; }

/* ===== 批量删除（多选模式） ===== */
.batch-del { margin-top: 7px; background: #3a3a3e; }
.batch-del.on { background: #c0392b; color: #fff; font-weight: 600; }
/* 清除本地数据：红色警示按钮（点击后仍需两次确认才执行） */
.wipe-local { background: #8e2b21; color: #fff; border: 1px solid #c0392b; }
.wipe-local:hover { background: #a83326; }
.wipe-local:active { filter: brightness(.9); }
.wipe-local:disabled { opacity: .55; cursor: not-allowed; }
/* 打包 / 导入打包工程 */
.pack-row { display: flex; gap: 6px; margin-top: 6px; }
.pack-row .full { width: auto; flex: 1 1 0; margin-top: 0; }
.pack-export { background: #2b5d8e; color: #fff; border: 1px solid #1f4a74; }
.pack-export:hover { background: #346ea3; }
.pack-import:hover { background: #3a3a3e; }
.pack-export:disabled, .pack-import:disabled { opacity: .55; cursor: not-allowed; }
/* 占位：两按钮合并到一行后，用同高隐藏按钮保留原面板高度，避免下方内容跳动 */
.batch-bar { display: flex; align-items: center; gap: 6px; margin-top: 7px; }
.batch-bar .batch-count { font-size: 12px; color: #ffd166; white-space: nowrap; flex: 1; }
.batch-bar button { font-size: 12px; padding: 6px 10px; }
/* 多选模式下卡片可选中：整圈描边 + 左上角对勾角标 */
.card.batch-sel { outline: 3px solid #ffd166; outline-offset: -3px; }
body.batch-mode .card { cursor: pointer; }
/* 多选模式：整张卡的所有交互（播放/拖动/控件）全部冻结，只保留「点空白处选中/取消」，
   顶栏控件、滑块、输入框等对用户不可用（与主控/被控的只读镜像一致，避免误操作） */
body.batch-mode .card,
body.batch-mode .card * { pointer-events: none; }
/* 仅卡片本身恢复接收点击用于选中（内部子元素继续 none，所以不会点到按钮/滑块） */
body.batch-mode .card { pointer-events: auto; }
body.batch-mode .card::after {
  content: '✓'; position: absolute; top: 6px; right: 6px; width: 20px; height: 20px;
  border-radius: 50%; background: #33333a; color: transparent; font-size: 13px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; pointer-events: none;
}
.card { position: relative; }
.card.batch-sel::after { background: #ffd166; color: #1a1a1a; }

/* ===== 网络端子同步 ===== */
.sync-badge { font-size: 10px; margin-left: 4px; padding: 1px 6px; border-radius: 8px; background: #33333a; color: #999; }
.sync-badge.on { background: #1d5a2a; color: #7ddc8a; }
.sync-badge.err { background: #5a1d1d; color: #ff9a9a; }
.pair-tip { font-size: 12px; line-height: 1.7; color: #aaa; margin: 0; }
.sync-status { font-size: 13px; color: #bbb; background: #2b2b30; border-radius: 8px; padding: 9px 10px; line-height: 1.6; }
.group-tab > span { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.group-tab .gt-del { background: transparent; color: inherit; padding: 0 4px; font-size: 15px; flex-shrink: 0; }

/* ===== 背包式网格画布 ===== */
.board {
  flex: 1 1 auto; min-height: 0;
  overflow: auto; background-color: #161618;
  display: grid; gap: 6px; padding: 6px;
  grid-auto-rows: min-content; align-content: start;
  touch-action: pan-y;
  padding-bottom: max(20px, env(safe-area-inset-bottom));
}
.board.dragging { touch-action: none; } /* 拖拽中禁止滚动，确保 iPad 拖得动 */
.empty-slot {
  border: 2px dashed #3a3a40; border-radius: 16px;
  display: flex; align-items: center; justify-content: center; text-align: center;
  color: #6a6a6e; font-size: 13px; min-height: 0;
  background: rgba(255,255,255,.02);
}
.empty-slot.drop-over { border-color: #ff8c1a; background: rgba(255,140,26,.10); color: #ff8c1a; }
.card.drop-over { border-color: #ff8c1a; }

/* ===== 拖拽导入音频文件 ===== */
/* 拖着文件进入卡片区：整块画布内侧描一圈橙色，提示"松手即导入" */
.board.file-drop { box-shadow: inset 0 0 0 3px #ff8c1a; }
/* 悬停在某张卡片上：蓝色内框 + 外发光，提示"松手即替换这张卡的音频"。
   用 .board .card 提高权重，避免被后面的 .card.playing 等状态样式盖掉。 */
.board .card.file-drop-target {
  box-shadow: inset 0 0 0 3px #4aa3ff, 0 0 16px rgba(74,163,255,.5);
}

/* ===== 卡片 ===== */
.card {
  background: #2c2c2e; border-radius: 16px;
  /* 内边距/间距随 --cs 缩放：卡片越小越紧凑；max() 给出最小可读下限 */
  padding: max(8px, calc(11px * var(--cs, 1)));
  display: flex; flex-direction: column; gap: max(6px, calc(9px * var(--cs, 1)));
  box-shadow: 0 2px 10px rgba(0,0,0,.4);
  border: 2px solid transparent;
  /* 淡入淡出用边框颜色渐变体现（JS 会按设定时长临时改写 transition 时长） */
  transition: border-color .25s linear, box-shadow .25s linear;
  /* pan-y：默认允许原生竖向滚动，卡片任意位置都能滑动列表；
     长按进入拖拽时由 JS 临时把本卡设为 touch-action:none 并拦截 touchmove，确保拖得动。 */
  /* align-self:start + 去掉 height:100%：卡片按自身内容高度显示，不被拉伸到整行高度，
     从而避免「卡片比同排最高卡矮时底部多出一块空白」；空槽仍默认 stretch 撑满网格。 */
  touch-action: pan-y; min-height: 0; align-self: start;
}
/* 全锁定：卡片整体变灰但保留可读（约五成去色 + 微暗），提示已禁用交互但非纯灰 */
.board.full-locked .card {
  filter: grayscale(0.55) brightness(0.9);
  opacity: .88;
}
.board.full-locked .card.playing {
  filter: grayscale(0.35) brightness(0.92);
}
.card.dragging { opacity: .22; }
.card.drag-armed { opacity: .35; border-color: #ff8c1a; cursor: grabbing; }
.drag-ghost {
  border: 2px solid #ff8c1a !important; transform: scale(1.02);
}
.card.playing { border-color: #ff3b30; box-shadow: 0 0 0 2px rgba(255,59,48,.5), 0 2px 14px rgba(255,59,48,.35); }
.card-head { display: flex; align-items: center; gap: 6px; }
.card .title-input, .card .title-text {
  flex: 1; min-width: 0; border: none; background: transparent;
  font-weight: 700; font-size: 15px; padding: 2px 4px; color: #fff;
}
/* 标题平时是只读文本，双击才变输入框；给一个「可编辑」的微提示 */
.card .title-text { cursor: text; min-height: 1.2em; }
.card .title-text:hover { text-decoration: underline dotted rgba(255,255,255,.35); text-underline-offset: 3px; }
.card .title-input:focus { outline: 1px solid #ff8c1a; border-radius: 6px; }
.card .c-bg, .card .c-font { width: 26px; height: 26px; padding: 0; border: none; background: none; }
.card .del-btn { background: rgba(0,0,0,.25); color: #fff; width: 24px; height: 24px; padding: 0; font-size: 13px; border-radius: 6px; }
.fade-badge { font-size: 11px; color: #ffd166; font-weight: 600; white-space: nowrap; }

/* ===== 远程音频标记 + 缓存状态 ===== */
/* 卡片上的「🌐 远程 + 缓存状态」单独一行，避免挤掉标题 */
.rc-row { display: flex; align-items: center; gap: 5px; flex-wrap: nowrap; overflow: hidden; min-height: max(16px, calc(20px * var(--cs, 1))); }
/* 没有标记（普通本地音频）也保留这一行的高度，使所有卡片等高、缓存状态变化时不再跳动 */
.rc-tag {
  flex: 0 0 auto; font-size: 10px; line-height: 1.7; padding: 0 6px; border-radius: 9px;
  background: #12304d; color: #9fd0ff; border: 1px solid #2b5c8f; white-space: nowrap;
}
.cache-chip {
  flex: 0 1 auto; font-size: 10px; line-height: 1.7; padding: 0 6px; border-radius: 9px;
  background: #33333a; color: #b9b9c0; border: 1px solid #4a4a52; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; cursor: pointer; user-select: none;
}
.cache-chip:hover { border-color: #7a7a85; color: #fff; }
.cache-chip.dl { background: #4a3a12; color: #ffd98a; border-color: #8a6a1f; }
.cache-chip.dl::before { content: ''; display: inline-block; width: 6px; height: 6px; margin-right: 4px; border-radius: 50%; background: #ffc830; animation: pulse 1s infinite; vertical-align: middle; }
.cache-chip.done { background: #17361f; color: #8ef0b6; border-color: #2e7a4f; }
.cache-chip.err { background: #43191c; color: #ff9a9a; border-color: #8a3a3a; }
/* 音源问题标签（文件丢失 / 源失效）：比缓存失败更醒目，点击可恢复 */
.cache-chip.src { background: #4a2a12; color: #ffc48a; border-color: #9a5a1f; font-weight: 600; }
.cache-chip.src:hover { background: #5c3517; color: #ffd9b0; }
/* 远程面板里的「诊断」结果行 */
.rc-probe { font-size: 11px; margin-top: 3px; }
.rc-probe.ok { color: #8ef0b6; }
.rc-probe.bad { color: #ff9a9a; }

/* 顶栏「远程缓存」按钮上的徽标 */
.rc-badge {
  display: inline-block; min-width: 26px; text-align: center; margin-left: 2px;
  font-size: 11px; font-weight: 700; padding: 0 5px; border-radius: 8px;
  background: #4a4a52; color: #ddd;
}
.rc-badge.pending { background: #7a4a10; color: #ffd9a8; }
.rc-badge.ok { background: #1f6b3f; color: #d6ffe6; }
#btnRemoteCache.has-pending { box-shadow: inset 0 0 0 1px #ff8c1a; }

/* ===== 浮动提示（播放/缓存失败原因） ===== */
#toastBox {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: max(16px, env(safe-area-inset-bottom)); z-index: 900;
  display: flex; flex-direction: column; gap: 6px; align-items: center;
  pointer-events: none; max-width: 92vw;
}
.toast-item {
  background: #2a2a2f; color: #f2f2f5; border: 1px solid #3d3d45;
  border-radius: 10px; padding: 8px 14px; font-size: 13px; line-height: 1.4;
  box-shadow: 0 6px 20px rgba(0,0,0,.5); transition: opacity .3s, transform .3s;
  max-width: 92vw;
}
.toast-item.ok { border-color: #2e7a4f; color: #b9f5cf; }
.toast-item.warn { border-color: #8a6a1f; color: #ffd98a; }
.toast-item.err { border-color: #8a3a3a; color: #ffb3b3; }
.toast-item.out { opacity: 0; transform: translateY(6px); }

/* ===== 远程缓存面板 ===== */
.rc-box { max-width: 560px; }
.rc-tip { margin: 0; font-size: 12px; line-height: 1.6; color: #aaa; }
.rc-tip b { color: #ffd166; }
.rc-summary {
  font-size: 12px; color: #cfcfd4; background: #2c2c30; border: 1px solid #3a3a42;
  border-radius: 10px; padding: 8px 10px; line-height: 1.6;
}
.rc-summary .rc-ok { color: #6ee7a5; font-weight: 700; }
.rc-summary .rc-warn { color: #ffc830; font-weight: 700; }
.rc-summary .rc-busy { color: #9fd0ff; }
.rc-summary .rc-none { color: #888; }
.rc-list { display: flex; flex-direction: column; gap: 8px; max-height: 46vh; overflow-y: auto; }
.rc-empty { color: #888; font-size: 13px; padding: 6px 2px; }
.rc-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: #2c2c30; border: 1px solid #3a3a42; border-radius: 10px; padding: 9px 11px;
}
.rc-main { min-width: 0; flex: 1; }
.rc-name { font-size: 13px; color: #fff; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rc-sub { font-size: 11px; color: #999; margin-top: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rc-err { font-size: 11px; color: #ff9a9a; margin-top: 3px; }
.rc-right { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.rc-right button { font-size: 12px; padding: 5px 10px; }
.rc-actions { flex-wrap: wrap; }

.big-play {
  /* 强调色跟随卡片颜色预设（--acc / --acc-fg 由 JS 注入），未设置则回退默认橙 */
  background: var(--acc, #ff8c1a);
  color: var(--acc-fg, #1a1a1a);
  font-weight: 700; font-size: 18px;
  padding: 16px; border-radius: 12px; width: 100%;
}
/* 选择器需带 .big-play 类，否则被全局 button:hover 的灰色覆盖 */
.big-play:hover { filter: brightness(1.10); }
.big-play:active { filter: brightness(.90); }
.big-play.on { background: #ff3b30; color: #fff; }  /* 播放中/停止：保持红色语义，不跟随预设 */

/* 播放按钮：淡入/淡出倒计时 + 进度条（覆盖层，不依赖重排） */
.big-play { position: relative; overflow: hidden; display: block; }
.big-play .pb-label { position: relative; z-index: 2; pointer-events: none; }
.big-play .pb-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0%; z-index: 1; background: rgba(255, 59, 48, .55); pointer-events: none; }
/* 淡变进行中：用中性底色（不抢红色语义），进度条由左向右生长；倒计时文字覆盖其上 */
.big-play.fading, .big-play.fading.on { background: #2c2c30; color: #fff; }

/* 停止全部：进度条效果（绿色生长，呼应暗绿激活态） */
button.full { position: relative; overflow: hidden; }
button.full .pb-label { position: relative; z-index: 2; pointer-events: none; }
button.full .pb-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0%; z-index: 1; background: rgba(255, 255, 255, .5); pointer-events: none; }

/* 总控区：停止全部 + ▶顺序 / ▶随机 并排 */
.master-btns { flex-wrap: wrap; }
.master-btns .play-all-row { flex: 1 1 auto; display: flex; flex-wrap: wrap; gap: 8px; min-width: 0; }
.master-btns .play-all-row .full { width: auto; flex: 1 1 auto; }
.play-mode-btn {
  background: #2c2c30; color: #fff; border: none; border-radius: 10px;
  padding: 9px 10px; font-size: 13px; white-space: nowrap; cursor: pointer;
  transition: background .15s; flex: 0 0 auto;
}
.play-mode-btn:hover { background: #3a3a3e; }
.play-mode-btn.active { background: #ff8c1a; color: #1a1a1a; font-weight: 700; }

/* 卡片「下一首播放」图标：与静音 / 循环图标同尺寸（背景与字号一致），点亮后背景尺寸不变，仅以「发光」作额外闪烁提示 */
.upnext {
  background: #2c2c30; font-size: 13px; padding: 4px 8px; line-height: 1;
  border: none; border-radius: 6px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, box-shadow .15s;
}
/* 「下一首播放」点亮：图标背景高亮呼吸闪烁（不再是外发光），背景尺寸保持不变 */
.upnext.on { color: #1a1a1a; animation: upnextFlash .85s ease-in-out infinite; }
@keyframes upnextFlash {
  0%, 100% { background: #7a4308; }
  50%      { background: #ffa63d; }
}
.card .upnext {
  font-size: max(11px, calc(13px * var(--cs, 1)));
  padding: calc(4px * var(--cs, 1)) calc(8px * var(--cs, 1));
  display: inline-flex; align-items: center; justify-content: center;
  width: max(calc(30px * var(--cs, 1)), 24px);
  height: max(calc(30px * var(--cs, 1)), 24px);
}

/* 走带控制：上一首 / 播放·暂停 / 下一首（位于打包工程下方）
   上一首 / 下一首为内联 SVG 图标：让按钮自身成为 flex 容器，图标与文字都能居中对齐 */
.transport-row { display: flex; gap: 6px; margin-top: 6px; }
.transport-btn {
  flex: 1 1 0; min-width: 0; background: #2c2c30; color: #fff; border: none;
  border-radius: 10px; padding: 9px 8px; font-size: 13px; cursor: pointer;
  white-space: nowrap; transition: background .15s, color .15s, opacity .15s;
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.transport-btn svg { width: 16px; height: 16px; display: block; flex: 0 0 auto; }
.transport-btn:hover { background: #3a3a3e; }
.transport-btn:active { filter: brightness(.92); }
/* 没有正在播放的音频时，播放 / 暂停按钮变灰且不可点击 */
.transport-btn.play-pause:disabled { background: #33343a; color: #6a6a72; cursor: not-allowed; opacity: .7; }
.transport-btn.play-pause.playing { background: #ff3b30; color: #fff; font-weight: 700; }
.transport-btn.play-pause.paused { background: #1f6b3f; color: #fff; font-weight: 700; }

/* 播放器模式 / 随机播放：沿用侧栏统一的 .sw-row + .switch 样式（字号与「循环播放」一致） */
.pm-right { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.sw-row.disabled { opacity: .45; cursor: not-allowed; }
.sw-row.disabled .sw-label { color: #6a6a72; }
/* 播放器模式行右侧的 X：仅在设置了「首次播放位置」时出现，用于取消该起点 */
.pm-x {
  margin-left: auto; flex: 0 0 auto; width: 24px; height: 24px; padding: 0;
  border: none; border-radius: 50%; background: #3a3a3e; color: #ddd;
  font-size: 15px; line-height: 1; cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s;
  -webkit-tap-highlight-color: transparent;
}
.pm-x:hover { background: #ff3b30; color: #fff; }
.pm-x:active { filter: brightness(.9); }
.pm-x[hidden] { display: none; }
/* 走带按钮禁用态（上一首在关闭模式下变灰） */
.transport-btn:disabled { background: #232327; color: #6a6a72; cursor: not-allowed; opacity: .7; }

/* 播放按钮长按需触发的拖拽选曲：白色发光源（blur 边缘） + 卡片高亮 */
#btnPlayPause { touch-action: none; }   /* 触屏长按时不让页面抢走手势 */
.drag-orb {
  position: fixed; width: 56px; height: 56px; border-radius: 50%; pointer-events: none; z-index: 9999;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle at 50% 50%, rgba(255,255,255,.95) 0%, rgba(255,255,255,.6) 42%, rgba(255,255,255,0) 72%);
  box-shadow: 0 0 26px 9px rgba(255,255,255,.6);
  filter: blur(1px);
}
/* 拖拽过程中，白色光源悬停的卡片临时高亮 */
.card.drag-over { outline: 2px solid #fff; outline-offset: -2px; box-shadow: 0 0 18px 3px rgba(255,255,255,.55); }
/* 被选为「播放起点」的卡片：持续白色边框（用 box-shadow，不与红色播放边框抢占 border） */
.card.start-selected { box-shadow: 0 0 0 2px #fff, 0 0 16px 2px rgba(255,255,255,.45); }

/* ===== 第一行：音量条（仅受拖拽控制，与电平完全分离）===== */
.vol-meter-wrap { display: flex; align-items: center; gap: 8px; }
.vol-meter { position: relative; flex: 1; height: 22px; display: flex; align-items: center; }
.vol-meter .vol {
  position: relative; width: 100%; background: transparent; z-index: 2; margin: 0;
  /* 音量滑块内容恒定（只随拖拽变），独立成层后 iOS 不会因下方电平每帧重绘
     而反复重新栅格化它，避免白色圆钮（橙边）出现左右抖动/发虚 */
  transform: translateZ(0);
  will-change: transform;
}

/* ===== 第二行：电平条（仅示意，随播放跳动；与音量条完全分开、互不干扰）===== */
.lvl-wrap {
  display: flex; align-items: center; gap: calc(6px * var(--cs, 1));
  margin-top: calc(2px * var(--cs, 1));   /* 紧贴上一行，尽量少增加高度 */
}
/* 电平条容器：布局隔离，防止每帧变化外溢影响其它控件 */
.lvl-wrap .vm-track {
  position: relative; flex: 1;
  /* 底色需明显亮于卡片背景(#2c2c2e)，否则整条电平条看起来像"没显示" */
  height: calc(8px * var(--cs, 1)); background: #3f3f47;
  border-radius: calc(4px * var(--cs, 1)); overflow: hidden;
  contain: layout paint;
}
/* 电平条：样式保持原样（绿→黄→红渐变）。
   用 clip-path 裁切而非改 width —— clip-path 只走绘制、不触发重排。 */
.lvl-wrap .vm-fill {
  height: 100%; width: 100%;
  background: linear-gradient(90deg, #27ae60 0%, #27ae60 55%, #f39c12 80%, #e74c3c 100%);
  -webkit-clip-path: inset(0 100% 0 0); clip-path: inset(0 100% 0 0);
  will-change: clip-path;
}
/* dB 数值必须「固定宽」：位数不同若改变实际宽度会挤动同行元素（iPad 上尤其明显） */
.lvl-wrap .db {
  font-size: 11px; color: #cfcfd4;
  width: 54px; min-width: 54px; max-width: 54px; flex: 0 0 54px;
  text-align: right; font-variant-numeric: tabular-nums;
  white-space: nowrap; overflow: hidden;
  contain: layout paint;
}

.ctrl { display: flex; flex-direction: column; gap: 7px; }
.ctrl .row { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #ccc; }
/* 允许滑块被时间文字压缩（否则窄卡片里 flex:1 的滑块撑破行） */
.ctrl .row .progress { flex: 1; min-width: 0; }
.ctrl .row span.lbl { width: 28px; color: #999; }
/* 时间信息紧跟进度条同行显示：省掉单独一行，抵消新增电平行的高度 */
.time { font-size: 11px; color: #999; text-align: right; }
.card .ctrl .row .time {
  flex: 0 0 auto; margin-left: 2px; line-height: 1;
  font-size: max(9px, calc(11px * var(--cs, 1)));
}
.fade-row { display: flex; align-items: center; gap: 6px; font-size: 11px; color: #bbb; flex-wrap: wrap; }
/* 卡片上的淡入 / 淡出：按钮形式，激活后高亮常驻 */
.fade-btn {
  background: #3a3a3e; color: #ddd; font-size: 12px; padding: 5px 12px; border-radius: 14px;
  border: 1px solid #4a4a4f; transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.fade-btn:hover { background: #4a4a4f; }
.fade-btn.on { color: #1a1a1a; font-weight: 700; border-color: transparent; }
.fade-btn.fin.on { background: #ff8c1a; }      /* 淡入激活：橙 */
.fade-btn.fout.on { background: #ffd166; }     /* 淡出激活：琥珀，便于区分 */
/* 卡片颜色预设：一排小色块，点一下同时套用背景色 + 字体色 */
.preset-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.preset-sw {
  width: 20px; height: 20px; padding: 0; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.28); cursor: pointer;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.35);
  transition: transform .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.preset-sw:hover { transform: scale(1.14); }
.preset-sw.on { border-color: #ff8c1a; box-shadow: 0 0 0 2px rgba(255,140,26,.4); }
.mute { background: #2c2c30; font-size: 15px; padding: 4px 8px; line-height: 1; }
.mute.on { background: #ff3b30; }
/* 单卡循环开关（紧挨静音图标右侧）：未开启时压暗作底，开启后点亮成绿色 */
.loop-one {
  background: #2c2c30; font-size: 13px; padding: 4px 8px; line-height: 1;
  transition: opacity .15s ease, filter .15s ease, background .15s ease, box-shadow .15s ease;
}
.loop-one.on {
  background: #1f6b3f; opacity: 1; filter: none;
}
.mute-row { display: flex; align-items: center; gap: 6px; margin-top: 4px; }

/* ===== 自定义 range 滑块（不依赖原生外观） =====
   已填充部分由 --p（百分比）切分渐变实现，JS 的 syncRangeFill() 负责实时更新。
   选择器保留 input[type="range"] 前缀以提高权重，避免被通用规则覆盖。 */
input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 20px; padding: 0; margin: 0;
  background: transparent; outline: none; cursor: pointer;
  --p: 100%;
  /* 轨道高 / 圆钮高用变量表达：圆钮偏移 = (轨道高 - 圆钮高) / 2，
     任何缩放比例下都精确垂直居中，不再靠手算的死值（手算值在 --cs/--sb 缩放时会偏）。 */
  --track-h: 8px;
  --thumb-h: 20px;
  /* 强调色可用 --acc 覆盖（卡片按颜色预设注入），未设置时回退为默认橙 */
  --fill: linear-gradient(90deg, var(--acc, #ff8c1a) 0%, var(--acc, #ff8c1a) var(--p), #4a4a4f var(--p), #4a4a4f 100%);
}
input[type="range"]::-webkit-slider-runnable-track {
  /* 必须 content-box：全局 *{box-sizing:border-box} 会让 1px 边框吃掉轨道高度，
     圆钮按被压扁后的高度对中，整体就偏低（卡片音量/进度圆钮"偏下"的根因）。 */
  box-sizing: content-box;
  height: var(--track-h); border-radius: calc(var(--track-h) / 2);
  background: var(--fill);
  border: 1px solid #55555c;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: var(--thumb-h); height: var(--thumb-h); border-radius: 50%;
  margin-top: calc((var(--track-h) - var(--thumb-h)) / 2);
  background: #fff; border: 2px solid var(--acc, #ff8c1a); cursor: pointer;
  box-shadow: 0 1px 5px rgba(0,0,0,.55);
}
input[type="range"]::-moz-range-track {
  box-sizing: content-box;
  height: var(--track-h); border-radius: calc(var(--track-h) / 2); background: #4a4a4f; border: 1px solid #55555c;
}
input[type="range"]::-moz-range-progress {
  box-sizing: content-box;
  height: var(--track-h); border-radius: calc(var(--track-h) / 2); background: var(--acc, #ff8c1a);
}
input[type="range"]::-moz-range-thumb {
  width: calc(var(--thumb-h) - 2px); height: calc(var(--thumb-h) - 2px); border-radius: 50%;
  background: #fff; border: 2px solid var(--acc, #ff8c1a); cursor: pointer;
}
/* 卡片音量条：已与电平条分行，滑块自身要显示填充（--p = 音量），只留圆钮即可。
   不再把轨道抹成透明——否则分离后音量条会变成"看不见的条"。 */
.card .vol-meter .vol { background: transparent; }
.card .vol-meter .vol::-webkit-slider-thumb {
  background: #fff; border-color: var(--acc, #fff); box-shadow: 0 1px 4px rgba(0,0,0,.6);
}
.card .vol-meter .vol::-moz-range-thumb { background: #fff; border-color: var(--acc, #fff); }
/* 进度条：轨道更细（尺寸与偏移交给 --track-h/--thumb-h 自动算，圆钮始终居中） */
.card .ctrl .progress { --track-h: calc(6px * var(--cs, 1)); }

/* ===== 卡片随「卡片尺寸」整体缩放 =====
   JS 按 state.cardSize 往每张卡片注入 --cs（220px 时 = 1.0，范围 0.78~1.25）。
   卡片内的字号 / 按钮 / 内边距 / 滑块轨道与圆钮全部乘上 --cs，
   卡片变小时内容同步缩小，避免标题、按钮挤在一起或换行错版。
   这些选择器与原规则同级或更高权重，且位置在后，故能安全覆盖。 */
.card {
  padding: calc(12px * var(--cs, 1));
  gap: calc(9px * var(--cs, 1));
  border-radius: calc(16px * var(--cs, 1));
}
.card-head { gap: calc(6px * var(--cs, 1)); }
.card .title-input, .card .title-text {
  font-size: max(11px, calc(15px * var(--cs, 1)));
  padding: calc(2px * var(--cs, 1)) calc(4px * var(--cs, 1));
}
.card .c-bg, .card .c-font { width: calc(26px * var(--cs, 1)); height: calc(26px * var(--cs, 1)); }
.card .del-btn {
  width: calc(24px * var(--cs, 1)); height: calc(24px * var(--cs, 1));
  font-size: max(9px, calc(13px * var(--cs, 1)));
}
.card .fade-badge { font-size: max(8px, calc(11px * var(--cs, 1))); }
/* 远程标记 / 缓存状态：随卡片尺寸一起缩放，避免窄卡片挤掉标题 */
.card .rc-tag, .card .cache-chip { font-size: max(8px, calc(10px * var(--cs, 1))); padding: 0 calc(5px * var(--cs, 1)); }
.card .rc-row { gap: calc(4px * var(--cs, 1)); }
.card .big-play {
  font-size: max(11px, calc(18px * var(--cs, 1)));
  padding: calc(15px * var(--cs, 1));
  border-radius: calc(12px * var(--cs, 1));
}
.card .vol-meter-wrap { gap: calc(8px * var(--cs, 1)); }
.card .vol-meter { height: calc(22px * var(--cs, 1)); }
.card .lvl-wrap { gap: calc(6px * var(--cs, 1)); margin-top: calc(2px * var(--cs, 1)); }
.card .lvl-wrap .vm-track { height: calc(8px * var(--cs, 1)); border-radius: calc(4px * var(--cs, 1)); }
.card .lvl-wrap .db {
  font-size: max(8px, calc(11px * var(--cs, 1)));
  width: calc(54px * var(--cs, 1)); min-width: calc(54px * var(--cs, 1)); max-width: calc(54px * var(--cs, 1)); flex: 0 0 calc(54px * var(--cs, 1));
}
.card .ctrl { gap: calc(7px * var(--cs, 1)); }
.card .ctrl .row { gap: calc(7px * var(--cs, 1)); font-size: max(9px, calc(12px * var(--cs, 1))); }
/* 注意：必须显式 min-width:0——否则会被侧栏新加的 .row .lbl{min-width:48px} 撑宽 */
.card .ctrl .row span.lbl { width: calc(28px * var(--cs, 1)); min-width: 0; }
.card .time { font-size: max(8px, calc(11px * var(--cs, 1))); }
/* 卡片内所有「行」一律不换行：空间不够时靠字号/尺寸继续缩小来腾位置，
   宁可字小也不要折成两行（避免缩放后排版错乱）。 */
.card .title-text,
.card .title-input { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card .big-play { white-space: nowrap; }
.card .time { white-space: nowrap; }
.card .lvl-wrap .db { white-space: nowrap; }
.card .ctrl .row { flex-wrap: nowrap; }
.card .ctrl .row span.lbl { white-space: nowrap; }
.card .fade-row { flex-wrap: nowrap; }
.card .fade-btn { white-space: nowrap; }

.card .fade-row { gap: calc(5px * var(--cs, 1)); font-size: max(8px, calc(11px * var(--cs, 1))); }
.card .fade-btn {
  font-size: max(9px, calc(12px * var(--cs, 1)));
  /* 左右内边距缩小幅度更大，给窄卡片留出更多文字空间 */
  padding: calc(4px * var(--cs, 1)) calc(9px * var(--cs, 1));
  border-radius: calc(13px * var(--cs, 1));
}
/* 颜色预设：改成 8 等分网格，卡片变窄时圆点自动变小而不是折行 */
.card .preset-row {
  display: grid; grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: calc(5px * var(--cs, 1));
}
.card .preset-sw {
  width: 100%; height: auto; aspect-ratio: 1 / 1;
  min-height: 10px; /* 老浏览器不支持 aspect-ratio 时的兜底高度，保证圆点可见 */
  max-width: calc(20px * var(--cs, 1)); max-height: calc(20px * var(--cs, 1));
  border-radius: 50%;
}
.card .mute {
  font-size: max(12px, calc(15px * var(--cs, 1)));
  padding: calc(4px * var(--cs, 1)) calc(8px * var(--cs, 1));
  display: inline-flex; align-items: center; justify-content: center; line-height: 1;
  border-radius: 6px;
}
.card .loop-one {
  font-size: max(11px, calc(13px * var(--cs, 1)));
  padding: calc(4px * var(--cs, 1)) calc(8px * var(--cs, 1));
  display: inline-flex; align-items: center; justify-content: center; line-height: 1;
  border-radius: 6px;
}
/* 卡片内的滑块：轨道高度、圆钮大小、圆钮偏移一起缩放，保证圆钮始终与轨道垂直居中 */
/* 只改 --track-h / --thumb-h：轨道高度、圆钮大小与偏移全部由变量推导，任何 --cs 下都精确居中 */
.card input[type="range"] {
  height: calc(20px * var(--cs, 1));
  --track-h: calc(8px * var(--cs, 1));
  --thumb-h: calc(16px * var(--cs, 1));
}
.card .ctrl .progress::-moz-range-thumb { width: calc(14px * var(--cs, 1)); height: calc(14px * var(--cs, 1)); }

/* ===== 弹窗 ===== */
.modal {
  position: fixed; inset: 0; background: rgba(0,0,0,.6);
  display: flex; align-items: center; justify-content: center; z-index: 50; padding: 16px;
}
.modal.hidden { display: none; }
.modal-box {
  background: #242427; border-radius: 16px; padding: 20px; width: 100%; max-width: 420px;
  max-height: 86vh; overflow-y: auto; display: flex; flex-direction: column; gap: 12px;
}
.modal-box h3 { margin: 0; font-size: 17px; }
.modal-box label { display: flex; flex-direction: column; gap: 5px; font-size: 13px; color: #bbb; }
.hidden { display: none !important; }
/* 通用文本输入弹窗（替代会暂停音频的原生 prompt） */
#inputModalField { width: 100%; box-sizing: border-box; margin: 2px 0 4px; padding: 10px 12px; font-size: 16px; border-radius: 10px; border: 1px solid #3a3a40; background: #2a2a2e; color: #fff; }
.cloud-box { max-width: 480px; }
/* 上传当前工程 */
.cloud-upload-bar {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: #2b2b30; border: 1px solid #3a3a42; border-radius: 12px; padding: 10px 12px;
}
.cloud-upload-bar .cub-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cloud-upload-bar .cub-info b { font-size: 14px; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cloud-upload-bar .cub-sub { font-size: 12px; color: #999; white-space: nowrap; }
.cloud-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 2px; }
.cloud-head span { font-size: 12px; color: #aaa; }
.cloud-head .mini { font-size: 12px; padding: 4px 10px; }
.cloud-list { display: flex; flex-direction: column; gap: 8px; max-height: 38vh; overflow-y: auto; }
.cloud-item { display: flex; align-items: center; justify-content: space-between; gap: 8px; background: #2c2c30; padding: 10px 12px; border-radius: 10px; }
.cloud-item .ci-info { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cloud-item .ci-name { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cloud-item .ci-meta { font-size: 11px; color: #8d8d95; white-space: nowrap; }
.cloud-item .ci-actions { display: flex; gap: 6px; flex: 0 0 auto; }
.cloud-item button { font-size: 12px; padding: 5px 10px; }
/* 云端工程删除按钮：红色警示（点击后仍需二次确认） */
.cloud-item button.danger { background: #e74c3c; color: #fff; border: 1px solid #c0392b; }
.cloud-item button.danger:hover { background: #ff5b49; }
.cloud-item button.danger:active { filter: brightness(.9); }
.cloud-item button.danger:disabled { opacity: .55; cursor: not-allowed; }
.cloud-empty { font-size: 13px; color: #8d8d95; padding: 10px 2px; line-height: 1.6; }
.cloud-empty.err { color: #e07a7a; }
.cloud-empty .ce-sub { color: #8d8d95; font-size: 12px; }
.cloud-progress { font-size: 13px; line-height: 1.5; color: #bbb; background: #2b2b30; border-radius: 8px; padding: 8px 10px; }
.cloud-progress.ok { color: #7ddc8a; }
.cloud-progress.err { color: #ff9a9a; }
button:disabled { opacity: .55; cursor: default; }
.help-text { font-size: 13px; line-height: 1.7; color: #ccc; }
.help-text code { background: #2c2c30; padding: 1px 5px; border-radius: 4px; color: #ff8c1a; }
.help-text .tip { color: #888; font-size: 12px; }
.help-text b { color: #fff; }
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; }

/* ===== 自适应：视口较矮时进一步压缩左栏，尽量整屏放得下 ===== */
@media (max-height: 800px) {
  .s-section { padding: 6px 10px; }
  .s-section h3 { margin-bottom: 4px; }
  .row { margin-top: 4px; }
  .dbmeter { height: clamp(56px, 11vh, 120px); }
  .clock { font-size: clamp(19px, 3vh, 26px); }
  .timer { font-size: clamp(14px, 2.2vh, 20px); }
  .group-tab { padding: 5px 9px; }
  .seg-btn { padding: 6px; }
  .master-btns { margin-top: 4px; }
  .topbar { padding: 6px 10px; gap: 6px; }
  .top-actions button { padding: 6px 9px; }
}

/* ===== 自适应：窄屏（竖屏 iPad / 小窗口）===== */
@media (max-width: 860px) {
  .sidebar { width: 268px; }
  .proj-name { width: 110px; }
  .np-bar { width: 190px; min-width: 190px; max-width: 190px; }
}

/* ===== 左栏整体缩放（--sb）=====
   JS 在「2 列仍放不下」时逐级下调 --sb（1.0 → 0.70），把左栏的字体、图标、
   按钮内边距、开关、滑块、间距一起缩小，尽量不用滚动就能看全。
   这里的选择器都带 .sidebar 前缀（权重 0-2-0 及以上），且位于文件最后，
   因此能稳定覆盖前面的基础规则与 @media 压缩规则。 */
.sidebar { --sb: 1; }

/* 左栏外边距 / 分块间距：与分块内边距一起等比缩放，缩放后整体仍等距 */
.sidebar { padding: calc(6px * var(--sb, 1)); gap: calc(6px * var(--sb, 1)); }
.sidebar.cols-2 { padding: calc(6px * var(--sb, 1)); gap: calc(6px * var(--sb, 1)); }
.sidebar .sb-col { gap: calc(6px * var(--sb, 1)); }

.sidebar .s-section {
  padding: calc(9px * var(--sb, 1)) calc(11px * var(--sb, 1));
  border-radius: calc(14px * var(--sb, 1));
}
.sidebar .s-section h3 {
  font-size: calc(11.5px * var(--sb, 1));
  margin-bottom: calc(7px * var(--sb, 1));
}
.sidebar .row { gap: calc(8px * var(--sb, 1)); margin-top: calc(5px * var(--sb, 1)); }
/* 标签固定宽度也要跟着缩放，否则缩放后字号变小、标签却还占着宽位置，滑块起点会偏右 */
.sidebar .row .lbl {
  font-size: calc(12px * var(--sb, 1));
  width: calc(50px * var(--sb, 1)); min-width: calc(50px * var(--sb, 1));
}
.sidebar .mval { font-size: calc(12px * var(--sb, 1)); min-width: calc(38px * var(--sb, 1)); }
.sidebar .stereo { margin-top: calc(4px * var(--sb, 1)); }
.sidebar .master-btns { gap: calc(8px * var(--sb, 1)); margin-top: calc(6px * var(--sb, 1)); }

/* 按钮 / 图标按钮 */
.sidebar button {
  font-size: calc(14px * var(--sb, 1));
  padding: calc(9px * var(--sb, 1)) calc(12px * var(--sb, 1));
  border-radius: calc(10px * var(--sb, 1));
}
.sidebar .icon-btn {
  min-width: calc(40px * var(--sb, 1));
  font-size: calc(16px * var(--sb, 1));
  padding: calc(8px * var(--sb, 1)) calc(10px * var(--sb, 1));
}
.sidebar button.full { margin-top: calc(6px * var(--sb, 1)); }

/* 播放模式 */
.sidebar .seg { gap: calc(6px * var(--sb, 1)); }
.sidebar .seg-btn { font-size: calc(12px * var(--sb, 1)); padding: calc(7px * var(--sb, 1)); }
.sidebar .sw-row { margin-top: calc(8px * var(--sb, 1)); gap: calc(8px * var(--sb, 1)); }
.sidebar .sw-label { font-size: calc(13px * var(--sb, 1)); }
.sidebar .switch { width: calc(46px * var(--sb, 1)); height: calc(26px * var(--sb, 1)); }
.sidebar .sw-slider { border-radius: calc(26px * var(--sb, 1)); }
.sidebar .sw-slider::before {
  left: calc(3px * var(--sb, 1)); top: calc(3px * var(--sb, 1));
  width: calc(20px * var(--sb, 1)); height: calc(20px * var(--sb, 1));
}
.sidebar .switch input:checked + .sw-slider::before { transform: translateX(calc(20px * var(--sb, 1))); }

/* 时间（时钟 / 计时器） */
.sidebar .clock { font-size: calc(clamp(22px, 3.6vh, 36px) * var(--sb, 1)); }
.sidebar .timer { font-size: calc(clamp(16px, 2.6vh, 28px) * var(--sb, 1)); }

/* 分组标签 */
.sidebar .group-tabs { gap: calc(4px * var(--sb, 1)); }
.sidebar .group-tab {
  gap: calc(6px * var(--sb, 1));
  padding: calc(6px * var(--sb, 1)) calc(10px * var(--sb, 1));
  border-radius: calc(10px * var(--sb, 1));
  font-size: calc(12px * var(--sb, 1));
}
.sidebar .group-tab .gt-del { font-size: calc(15px * var(--sb, 1)); padding: 0 calc(4px * var(--sb, 1)); }
.sidebar .group-pager { gap: calc(8px * var(--sb, 1)); margin-top: calc(8px * var(--sb, 1)); }
.sidebar .group-pager .icon-btn { min-width: calc(34px * var(--sb, 1)); }
.sidebar .page-info { font-size: calc(12px * var(--sb, 1)); }

/* 总音量：竖条 dB 表 + 主音量 */
.sidebar .master-vol-block { gap: calc(14px * var(--sb, 1)); }
.sidebar .dbmeter-wrap { gap: calc(6px * var(--sb, 1)); }
.sidebar .dbmeter {
  width: calc(24px * var(--sb, 1));
  height: calc(clamp(72px, 14vh, 168px) * var(--sb, 1));
  border-radius: calc(12px * var(--sb, 1));
}
.sidebar .dbm-val { font-size: calc(11px * var(--sb, 1)); min-width: calc(54px * var(--sb, 1)); }
.sidebar .master-right { gap: calc(8px * var(--sb, 1)); }

/* 左栏滑块：轨道高度、圆钮尺寸与偏移一起缩放，保证圆钮始终与轨道垂直居中 */
.sidebar input[type="range"] {
  height: calc(20px * var(--sb, 1));
  --track-h: calc(8px * var(--sb, 1));
  --thumb-h: calc(20px * var(--sb, 1));
}
.sidebar input[type="range"]::-webkit-slider-thumb {
  width: var(--thumb-h); height: var(--thumb-h);
  margin-top: calc((var(--track-h) - var(--thumb-h)) / 2);
}
.sidebar input[type="range"]::-moz-range-thumb { width: calc(var(--thumb-h) - 2px); height: calc(var(--thumb-h) - 2px); }

/* 两列模式下按比例微调的项（放在最后，保证覆盖上面同名规则） */
.sidebar.cols-2 .master-vol-block { gap: calc(10px * var(--sb, 1)); }
/* ===== iPad（含 iPad mini）适配 =====
   断点覆盖 iPad mini 竖屏(744) / 横屏(1133) 及其他 iPad：
   - 顶栏在窄横排下收紧（按钮/弹窗总控/正在播放压缩），避免折成三行；
   - 触控目标放大到 ≥34px（Apple HIG 建议触点 ≥44px，取平衡值）；
   - 卡片滑块触控高度加大（触感区变大，外观不变）。 */
@media (min-width: 700px) and (max-width: 1200px) {
  .topbar { gap: 6px; padding-left: 10px; padding-right: 10px; }
  .brand { font-size: 13px; }
  .proj-name { width: 96px; }
  .top-actions button { font-size: 11px; padding: 6px 8px; }
  .fade-master { gap: 4px; padding: 3px 8px; }
  .fm-btn { font-size: 11px; padding: 4px 8px; }
  input[type="range"].fm-range { flex: 0 0 64px; width: 64px; }
  .fm-val { min-width: 32px; font-size: 11px; }
  .np-bar { width: 180px; min-width: 180px; max-width: 180px; }
  .np-cap { font-size: 11px; }
  .np-chip { font-size: 11px; padding: 2px 8px; }
  .np-chip .np-name { max-width: 8em; }
  /* 卡片触控优化：按钮加高，滑块触控区加宽加高（视觉随 --cs 缩放，但触控高度有下限） */
  /* 取消原来 14px 的额外底部内边距（正是「底部空块」来源之一），改为随 --cs 等比收紧 */
  .card { padding: max(calc(8px * var(--cs, 1)), 7px); }
  .card .big-play { padding: max(calc(10px * var(--cs, 1)), 9px) 0; font-size: max(calc(14px * var(--cs, 1)), 13px); }
  .fade-btn { padding: max(calc(5px * var(--cs, 1)), 7px) max(calc(12px * var(--cs, 1)), 12px); }
  /* 按钮外框 = 图标字号(15px*--cs)的约 2 倍，随 --cs 一起缩放；下限 24px 兼顾触控。
     原来钉死 34px 下限导致卡片缩小时只有图标缩、外框不缩，现改为与外框同步缩放。 */
  .card .mute { width: max(calc(30px * var(--cs, 1)), 24px); height: max(calc(30px * var(--cs, 1)), 24px); }
  .card .loop-one { width: max(calc(30px * var(--cs, 1)), 24px); height: max(calc(30px * var(--cs, 1)), 24px); }
  /* 触控高度取「缩放值」与「24px 下限」的较大者：卡片缩小时命中区也不至于点不到，且与图标同步缩放 */
  .card .vol-meter { height: max(calc(22px * var(--cs, 1)), 34px); }
  .card input[type="range"] { height: max(calc(20px * var(--cs, 1)), 34px); }
  /* 触控放大：只改 --thumb-h，圆钮偏移由变量自动重算，视觉保持垂直居中 */
  .card .vol-meter .vol { --thumb-h: max(calc(16px * var(--cs, 1)), 18px); }
  .card .ctrl .progress { height: max(calc(20px * var(--cs, 1)), 30px); --thumb-h: max(calc(14px * var(--cs, 1)), 16px); }
  .sidebar { width: 264px; }
  .sidebar.cols-2 { width: 420px; }
}

/* 竖屏 iPad mini / 窄平板：左栏与卡片都收窄，右侧多排卡片 */
@media (orientation: portrait) and (max-width: 820px) {
  .sidebar { width: 232px; }
  .sidebar.cols-2 { width: 380px; }
  .row .lbl { width: 44px; min-width: 44px; font-size: 11.5px; }
}

/* ===== iOS Safari 触控修正 =====
   iOS 对 input[type=range] 的命中判定依赖原生尺寸，自定义外观后必须：
   - 触控区保持足够大；-webkit-appearance 已在全局设置；
   - 防止 iOS 把水平拖动当成页面滚动而吞掉 input 事件。 */
input[type="range"] { touch-action: pan-y; }
.card input[type="range"], .vol-meter, .lvl-wrap, .ctrl { touch-action: none; }   /* 卡片内：禁止页面滚动抢手势 */

/* ============ 网络同步：主控/被控 + 设备发现 ============ */
.sync-box { max-width: 460px; }
.sync-status { margin: 4px 0 10px; padding: 8px 10px; background: #2a2a2e; border-radius: 10px; font-size: 13px; color: #d0d0d6; }
.sync-role { display: flex; gap: 8px; margin: 8px 0 10px; }
.sync-role .seg-btn { flex: 1; }
.sync-role .seg-btn.active { background: #ff8c1a; color: #1a1a1a; }
.sync-tip { font-size: 12px; line-height: 1.5; color: #b8b8c0; background: #232327; border: 1px solid #2f2f36; border-radius: 10px; padding: 8px 10px; margin-bottom: 10px; }
.sync-tip b { color: #ffb366; }
.sync-play-sync { display: flex; align-items: center; gap: 10px; margin: 8px 0 10px; padding: 8px 10px; background: #232327; border: 1px solid #2f2f36; border-radius: 10px; }
.sync-play-sync .switch { flex-shrink: 0; }
.sync-play-label { font-size: 13px; color: #cfcfd6; line-height: 1.4; }
.sync-code-row { display: flex; align-items: center; gap: 8px; margin: 8px 0; }
.sync-code-row .lbl { width: 80px; flex-shrink: 0; color: #c8c8d0; font-size: 13px; }
.sync-code-row code { flex: 1; background: #111; border: 1px solid #333; border-radius: 8px; padding: 6px 10px; font-size: 15px; letter-spacing: 1px; color: #ffd9a8; user-select: all; }
.sync-code-row input { flex: 1; }
.device-list-wrap { margin: 10px 0; background: #232327; border: 1px solid #2f2f36; border-radius: 10px; padding: 8px 10px; }
.device-list-wrap .dl-cap { font-size: 12px; color: #9a9aa2; margin-bottom: 6px; }
.device-list { display: flex; flex-direction: column; gap: 6px; }
.device-item { display: flex; align-items: center; gap: 8px; padding: 6px 8px; background: #2a2a2e; border-radius: 8px; font-size: 13px; }
.device-item .d-name { flex: 1; }
.device-item .d-role { font-size: 11px; padding: 2px 8px; border-radius: 999px; background: #3a3a40; color: #cfcfd6; }
.device-item .d-role.master { background: #ff8c1a; color: #1a1a1a; }
.device-item .d-role.slave { background: #4aa3ff; color: #06203a; }
.device-item .d-state { font-size: 11px; color: #7fd18a; }
.device-item .d-state.off { color: #888; }

/* ============================================================
   卡片图标：循环 / 下一首 由 emoji 换成内联 SVG
   —— 不依赖系统字形，尺寸随按钮 font-size（--cs）走，颜色随 currentColor
   ============================================================ */
.loop-one svg, .upnext svg { display: block; pointer-events: none; }
/* 未点亮时压暗，点亮后由 .on 的背景色 + 文字色接管，状态一眼可辨 */
.loop-one:not(.on) { color: #9a9aa2; }
.upnext:not(.on) { color: #9a9aa2; }
.loop-one.on { color: #fff; }

/* ============================================================
   播放器模式：右侧「音频列表」排版
   顺序播放 = 依本列表自上而下；随机播放 = 在本列表里随机挑。
   仅在 .board.as-list 下生效，原来的背包网格完全不受影响。
   ============================================================ */
.board.as-list { grid-template-columns: 1fr; gap: 5px; counter-reset: listno; }
.board.as-list .empty-slot { display: none; }
.board.as-list .card {
  counter-increment: listno;
  flex-direction: row; align-items: center;
  /* 紧凑基线：先保证 iPad 竖屏（约 500px 可用宽）也不溢出，宽屏再由下面的 @media 放宽 */
  gap: 6px; padding: 5px 8px; border-radius: 10px;
  min-height: 44px; align-self: stretch;
}
/* 行首序号即播放顺序 */
.board.as-list .card::before {
  content: counter(listno);
  flex: 0 0 auto; width: 20px; text-align: center;
  font-size: 11px; font-weight: 700; color: #9a9aa2;
  font-variant-numeric: tabular-nums;
}
.board.as-list .card.playing::before { color: #ff3b30; }
/* ===== iPad 适配：列表行只保留「名字 / 播放 / 音量条 / 电平 / 时间」=====
   原来的「进度条 + 淡入淡出 + 静音 + 循环 + 下一首 + 远程标记」在 iPad 一行里
   必然把右侧顶出可视区，这里统一收起（需要改动请关掉播放器模式回到卡片网格）。
   横向空间优先级：名字可压缩（省略号）> 音量条 > 电平 > 固定不可缩元素。 */
/* 名字列：固定基宽（不再按文字长短自适应），各行宽度一致＝整列对齐；
   空间仍不够时由它优先 shrink（权重 3）并交给 ellipsis 截断。
   min-width:0 让它能被压缩到 0，max-width 兜住超宽屏不至于过分拉长。 */
.board.as-list .card-head { flex: 1 3 180px; min-width: 0; max-width: 320px; }
.board.as-list .card-head .title-text,
.board.as-list .card-head .title-input {
  flex: 1 1 auto; min-width: 0; display: block; font-size: 12px;
}
/* 收起：编辑类控件 + 远程/缓存标记 + 淡入淡出/静音/循环/下一首 + 进度条及其「进度」标签 */
.board.as-list .card-head .c-bg,
.board.as-list .card-head .c-font,
.board.as-list .card-head .del-btn,
.board.as-list .card-head .fade-badge,
.board.as-list .rc-row,
.board.as-list .preset-row,
.board.as-list .fade-row,
.board.as-list .ctrl .row span.lbl,
.board.as-list .ctrl .row .progress { display: none; }

/* 播放按钮：横排小按钮 */
.board.as-list .card .big-play {
  flex: 0 0 auto; width: 58px; padding: 7px 0; font-size: 12px;
  border-radius: 8px;
}
/* 音量条 */
.board.as-list .card .vol-meter-wrap { flex: 1 1 64px; min-width: 52px; gap: 0; }
.board.as-list .card .vol-meter { height: 16px; }
/* 电平条：窄屏隐藏 dB 数字，把宽度全部让给条本身（否则条只剩几像素看不见） */
.board.as-list .card .lvl-wrap { flex: 1 1 72px; min-width: 48px; gap: 4px; margin-top: 0; }
.board.as-list .card .lvl-wrap .vm-track { height: 7px; }
.board.as-list .card .lvl-wrap .db { display: none; }
/* 时间：只留文字，紧贴行尾。
   固定最小宽度 + 等宽数字：各位数不同的时长不会反挤名字列，保证整列对齐一致
   （fmt() 输出 m:ss，12ch 足够覆盖 "99:59 / 99:59"；更长时用 auto 自然加宽，不截断）。 */
.board.as-list .ctrl {
  flex: 0 0 auto; min-width: 0;
  flex-direction: row; align-items: center; gap: 0;
}
.board.as-list .ctrl .row { flex: 0 0 auto; min-width: 0; gap: 0; }
.board.as-list .card .ctrl .row .time {
  font-size: 10px; margin-left: 0;
  flex: 0 0 auto; min-width: 12ch; text-align: right;
  font-variant-numeric: tabular-nums;
}
.board.as-list .card:hover { box-shadow: 0 0 0 1px rgba(255,255,255,.14), 0 2px 10px rgba(0,0,0,.4); }
.list-empty { color: #6a6a6e; font-size: 13px; padding: 18px; text-align: center; }

/* 宽一些的屏（iPad 横屏 1024 起）给列表行多一点呼吸空间，仍不引入新控件 */
@media (min-width: 900px) {
  .board.as-list .card { gap: 9px; padding: 6px 11px; min-height: 48px; }
  .board.as-list .card::before { width: 24px; font-size: 12px; }
  /* 宽屏下名字列整体加宽（各行仍然保持一致） */
  .board.as-list .card-head { flex-basis: 240px; max-width: 460px; }
  .board.as-list .card-head .title-text,
  .board.as-list .card-head .title-input { font-size: 13px; }
  .board.as-list .card .big-play { width: 70px; font-size: 13px; padding: 8px 0; }
  .board.as-list .card .vol-meter-wrap { flex: 1 1 92px; }
  .board.as-list .card .vol-meter { height: 20px; }
  .board.as-list .card .lvl-wrap { flex: 1 1 96px; }
  .board.as-list .card .lvl-wrap .vm-track { height: 8px; }
  /* 宽屏放得下了，恢复 dB 数值（固定宽，避免位数变化挤动同行） */
  .board.as-list .card .lvl-wrap .db {
    display: block;
    width: 46px; min-width: 46px; max-width: 46px; flex: 0 0 46px; font-size: 10px;
  }
  .board.as-list .card .ctrl .row .time { font-size: 11px; }
}
