/* === Music-AI-Assistant — design tokens (slate + indigo) =========================== */
:root {
  --brand-indigo: #4f46e5;
  --brand-indigo-soft: #6366f1;
  --brand-indigo-bg: #eef2ff;
  --success: #10b981;
  --warning: #f59e0b;
  --danger: #ef4444;
  --info: #0ea5e9;

  --bg: #f8fafc;
  --surface: #ffffff;
  --surface-2: #f1f5f9;
  --surface-3: #e2e8f0;
  --border: #e2e8f0;
  --border-strong: #cbd5e1;
  --text: #0f172a;
  --text-muted: #64748b;
  --text-faint: #94a3b8;

  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;

  --fs-h1: 1.5rem;
  --fs-h2: 1.25rem;
  --fs-body: 0.95rem;
  --fs-small: 0.85rem;

  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08);
}

html, body {
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', 'PingFang SC', 'Microsoft YaHei', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: var(--fs-body);
}

/* === navbar ================================================================= */
.app-navbar {
  background: linear-gradient(135deg, var(--brand-indigo) 0%, var(--brand-indigo-soft) 100%);
}

/* navbar 走自定义的深色渐变背景,把品牌名/链接都显式改成白色,避免
   沿用 Bootstrap 默认的深色 rgba(0,0,0,.9) —— 暗字落深紫底上不协调。 */
.app-navbar .navbar-brand,
.app-navbar .navbar-brand:hover,
.app-navbar .navbar-brand:focus {
  color: #fff;
  text-shadow: 0 1px 2px rgba(15, 23, 42, 0.25);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}

/* 🎵 logo 徽章 —— 默认 emoji 在深紫渐变上偏淡、和背景太融,套个白底圆+阴影
   让它跳出来,也更像正经品牌图标。 */
.app-navbar .navbar-brand .brand-logo {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  line-height: 1;
  box-shadow: 0 2px 6px rgba(15, 23, 42, 0.25);
  text-shadow: none;
}

/* 顶部 outline-light 按钮里的 emoji 图标(⚙/👥 等) —— 直接用 emoji 本色,不套
   白底徽章,让菜单风格统一、无装饰元素。 */

/* navbar-toggler(汉堡按钮)—— Bootstrap 默认边框是 rgba(0,0,0,.1)、图标 SVG 描边
   也是黑色,落在深紫渐变上完全看不见。这里手动换成白边 + 白图标 + 白 focus ring。 */
.app-navbar .navbar-toggler {
  border-color: rgba(255, 255, 255, 0.6);
  color: #fff;
}
.app-navbar .navbar-toggler:focus {
  box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.25);
}
.app-navbar .navbar-toggler-icon {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.85%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

/* 移动端(< md):折叠展开后菜单从上往下垂直排,按钮/下拉 trigger 撑满宽度,便于
   触屏点击;桌面端 (.navbar-expand-md >= md) 走默认的水平右对齐布局,不受影响。 */
@media (max-width: 767.98px) {
  .app-navbar .navbar-collapse .navbar-menu-inner {
    flex-direction: column;
    align-items: stretch;
    gap: 0.4rem;
    padding-top: 0.5rem;
  }
  .app-navbar .navbar-collapse .navbar-menu-inner > .btn,
  .app-navbar .navbar-collapse .navbar-menu-inner > .user-menu {
    width: 100%;
  }
  .app-navbar .navbar-collapse .user-trigger {
    width: 100%;
    justify-content: space-between;
    padding: 0.35rem 0.7rem;
  }
}

/* 当前用户 dropdown trigger — 浅色填充 + caret,让 trigger 一眼能看出
   是菜单(单行高度与 outline-light 按钮齐平,不撑高 navbar)。 */
.user-menu .user-trigger {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: var(--radius-sm);
  padding: 0.2rem 0.55rem;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.user-menu .user-trigger:hover,
.user-menu .user-trigger:focus,
.user-menu .user-trigger[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.22);
  border-color: rgba(255, 255, 255, 0.6);
  color: #fff;
  box-shadow: none;
}
.user-menu .user-trigger::after { display: none; }   /* 去掉 BS 默认的 dropdown caret */

.user-avatar {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: linear-gradient(135deg, #fff 0%, #e0e7ff 100%);
  color: var(--brand-indigo);
  font-weight: 700;
  font-size: 0.78rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.user-name {
  color: #fff;
  font-weight: 500;
  font-size: 0.88rem;
  line-height: 1;
}
.user-caret {
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.7rem;
  margin-left: 0.1rem;
}

/* dropdown 自身:圆角 + 顶边对齐 trigger */
.user-menu .dropdown-menu {
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  padding: 0.35rem 0;
  min-width: 200px;
  margin-top: 6px;
}
.user-menu .dropdown-header {
  padding: 0.45rem 1rem 0.25rem;
  color: var(--text);
}
.user-menu .dropdown-item {
  padding: 0.45rem 1rem;
  font-size: 0.9rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.user-menu .dropdown-item:hover,
.user-menu .dropdown-item:focus {
  background: var(--brand-indigo-bg);
  color: var(--brand-indigo);
}
.user-menu .dropdown-item.text-danger:hover,
.user-menu .dropdown-item.text-danger:focus {
  background: #fef2f2;
  color: var(--danger);
}

/* === cards / forms / tables / badges ======================================== */
.card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  background: var(--surface);
}
.card .card-title {
  font-weight: 600;
  color: var(--text);
}
.form-control, .form-select {
  border-radius: var(--radius-sm);
  border-color: var(--border);
  color: var(--text);
  font-size: var(--fs-body);
}
.form-control:focus, .form-select:focus {
  border-color: var(--brand-indigo);
  box-shadow: 0 0 0 0.2rem rgba(79, 70, 229, 0.18);
}
.btn-primary {
  background: var(--brand-indigo);
  border-color: var(--brand-indigo);
}
.btn-primary:hover, .btn-primary:focus {
  background: var(--brand-indigo-soft);
  border-color: var(--brand-indigo-soft);
}
.btn-outline-primary {
  color: var(--brand-indigo);
  border-color: var(--brand-indigo);
}
.btn-outline-primary:hover {
  background: var(--brand-indigo);
  color: #fff;
}

.badge {
  font-weight: 500;
  border-radius: var(--radius-sm);
  padding: 0.35em 0.6em;
}
.status-pending  { background: var(--surface-3); color: var(--text-muted); }
.status-running  { background: var(--info); color: #fff; }
.status-succeeded { background: var(--success); color: #fff; }
.status-failed   { background: var(--danger); color: #fff; }
.status-cancelled { background: var(--warning); color: #fff; }

/* === tables ================================================================= */
.table > :not(caption) > * > * {
  padding: 0.65rem 0.75rem;
}
.table thead th {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: var(--fs-small);
  color: var(--text-muted);
  background: var(--surface-2);
  border-bottom: 1px solid var(--border-strong);
}
.table tbody tr + tr > * {
  border-top: 1px solid var(--border);
}

/* === empty-state card ======================================================= */
.empty-state {
  background: linear-gradient(135deg, #f8fafc 0%, #eef2ff 100%);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
}

/* === songs list — mobile card view (< md) ================================== */
/* 桌面端走 .table(见 .songs-view-desktop),移动端把每首歌渲染成独立 card:
   左 56px 海报缩略图 + 右标题/元信息 + 右侧悬浮删除按钮,整张卡片可点进详情。
   BS 的 d-md-none / d-none.d-md-block 控制可见性,JS 不监听 resize 也能切。 */
.song-card-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.song-card {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
  padding: 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.song-card:hover,
.song-card:focus-within {
  border-color: var(--brand-indigo);
  box-shadow: var(--shadow-md);
}
.song-card-link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex: 1 1 auto;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}
.song-card-link:hover,
.song-card-link:focus {
  color: inherit;
  text-decoration: none;
}
.song-card-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.song-card-title {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--brand-indigo);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.song-card-meta {
  font-size: 0.8rem;
  color: var(--text);
}
.song-card-meta-muted {
  color: var(--text-muted);
  font-size: 0.75rem;
}
.song-card-delete {
  flex: 0 0 auto;
  align-self: center;
  padding: 0.3rem 0.55rem;
  font-size: 0.9rem;
  line-height: 1;
  border-radius: var(--radius-sm);
}

/* 缩略图 —— 桌面表格里是 48×48,移动 card 里 56×56 看起来更协调;
   桌面 .table img 的 inline style 仍走老尺寸,这条规则只影响 card 容器内的 .song-thumb。 */
.song-thumb {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  flex-shrink: 0;
  background: var(--surface-2);
}
/* 缩略图同时是「点击放大」的触发器 — 给个放大镜光标,比默认箭头更明确。 */
.song-thumb.image-zoom-trigger { cursor: zoom-in; }
.song-thumb-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  color: var(--text-muted);
  border: 1px dashed var(--border-strong);
}

/* 桌面表格里的缩略图覆盖为 48×48,与移动 card 区分开 */
.songs-view-desktop .song-thumb {
  width: 48px;
  height: 48px;
}

/* === jobs list — mobile card view (< md) ==================================== */
/* 桌面端走 .table(见 .jobs-view-desktop),移动端把每个 job 渲染成独立 card:
   顶部 id + 状态徽章,中部 provider/model + 全宽进度条 + 错误行(若有),
   底部操作按钮组右对齐。BS 的 d-md-* 控制可见性,JS 不监听 resize。 */
.job-card-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.job-card {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.job-card:hover,
.job-card:focus-within {
  border-color: var(--brand-indigo);
  box-shadow: var(--shadow-md);
}
.job-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
}
.job-card-id {
  font-size: 0.85rem;
  color: var(--text-muted);
  font-weight: 500;
}
.job-card-inspiration {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  line-height: 1.35;
  word-break: break-word;
  /* 长文本最多两行 —— 移动端单 card 不该被一段灵感撑到三屏高 */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.job-inspiration {
  /* 桌面表格里灵感列 —— 两行 ellipsis;鼠标悬停通过 title 看全文。
     去掉「进度/错误」列后 灵感 是表格主信息列,扩到 560px 让长 prompt 一眼可读 */
  max-width: 560px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
}
.job-card-meta {
  font-size: 0.85rem;
  color: var(--text);
}
.job-card-progress {
  height: 6px;
  margin: 0;
}
.job-card-error {
  font-size: 0.78rem;
  color: var(--danger);
  background: #fef2f2;
  border-left: 3px solid var(--danger);
  padding: 0.3rem 0.55rem;
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  word-break: break-word;
}
.job-card-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.4rem;
  padding-top: 0.25rem;
  border-top: 1px solid var(--border);
  margin-top: 0.15rem;
}

/* === music-specific ========================================================= */
.music-result audio {
  width: 100%;
  accent-color: var(--brand-indigo);
}
.music-result .progress {
  height: 4px;
}

.btn-check:checked + .btn-outline-secondary {
  background: var(--brand-indigo);
  color: #fff;
  border-color: var(--brand-indigo);
}

/* chip-multiselect hover tweak */
.btn-check:focus + .btn-outline-secondary {
  box-shadow: 0 0 0 0.2rem rgba(79, 70, 229, 0.18);
}

textarea { resize: vertical; }

/* sticky result panel scrollbar (Safari) */
.card.sticky-top::-webkit-scrollbar { width: 8px; }
.card.sticky-top::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 4px; }

/* progress bar height override */
.progress { background-color: var(--surface-3); }

/* === settings — provider card view (< md) ================================== */
/* 桌面端走 .table(由 .providers-view-desktop 包裹),移动端把每个 provider 配置
   渲染成独立 card:head 名字+协议 / section 字段(带小标签) / toggle-row 启用+key 状态
   / actions 操作按钮。结构参考 .job-card*(都是 head/body/actions 三段),
   视觉权重刻意低于列表卡 —— 配置卡不像歌曲卡那样可点进详情,留更多留白。
   BS 的 d-md-none / d-none.d-md-block 控制可见性,JS 不监听 resize。 */
.providers-view-mobile {
  display: block;
}
.provider-card-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.provider-card {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.provider-card:hover,
.provider-card:focus-within {
  border-color: var(--brand-indigo);
  box-shadow: var(--shadow-md);
}
.provider-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.provider-card-head-main {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  min-width: 0;
  flex: 1 1 auto;
}
.provider-card-title {
  font-weight: 600;
  font-size: 0.98rem;
  color: var(--text);
  /* 长 display_name(中文)允许换行,不被 badge 撑出单行 */
  overflow-wrap: anywhere;
}
.provider-card-head-meta {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  flex-shrink: 0;
}
.provider-card-section {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.provider-card-section-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  font-weight: 600;
}
.provider-card-section-body {
  font-size: 0.85rem;
  color: var(--text);
  word-break: break-word;
  /* 长模型名(如 gpt-4-32k-0613-instruct-completion)允许 chip 内部断行,
     防止单个 chip 撑破 card 宽度。 */
  overflow-wrap: anywhere;
}
.provider-card-section-body code {
  font-size: 0.8rem;
  word-break: break-all;
}
.provider-card-toggle-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding-top: 0.35rem;
  border-top: 1px solid var(--border);
}
.provider-card-toggle {
  flex: 0 0 auto;
}
.provider-card-key {
  flex: 1 1 auto;
  min-width: 0;
  text-align: right;
  font-size: 0.82rem;
  overflow-wrap: anywhere;
}
.provider-card-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.4rem;
  padding-top: 0.35rem;
  border-top: 1px solid var(--border);
}

/* === users list — mobile card view (< md) ================================== */
/* 桌面端走 .table(见 .users-view-desktop),移动端把每个用户渲染成独立 card:
   head 用户名(粗体)+ 权限徽章 / body 字段行(创建时间/上次登录,带小标签) /
   actions 操作按钮组右对齐,「自己」行的 actions 走提示文案而非按钮。
   BS 的 d-md-none / d-none.d-md-block 控制可见性,JS 不监听 resize。
   视觉风格对齐 .job-card / .provider-card,字段更少故留白略小。 */
.user-card-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.user-card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.user-card:hover,
.user-card:focus-within {
  border-color: var(--brand-indigo);
  box-shadow: var(--shadow-md);
}
.user-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.user-card-name {
  font-weight: 600;
  font-size: 0.98rem;
  color: var(--text);
  overflow-wrap: anywhere;
}
.user-card-role {
  flex-shrink: 0;
}
.user-card-fields {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.85rem;
}
.user-card-field {
  display: flex;
  gap: 0.4rem;
  align-items: baseline;
}
.user-card-field-label {
  flex: 0 0 4.2em;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  font-weight: 600;
}
.user-card-field-value {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text);
  word-break: break-word;
}
.user-card-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.4rem;
  padding-top: 0.4rem;
  border-top: 1px solid var(--border);
}
.user-card-actions-hint {
  width: 100%;
  font-size: 0.82rem;
  color: var(--text-muted);
  padding-top: 0.4rem;
  border-top: 1px solid var(--border);
}
