/* ============================================================
   设计令牌 · 磨砂玻璃体系（2026-08-03）
   ============================================================
   基准：水马网页UI设计方向/AquaHorse Homepage Options.dc.html
   由来：全站原本是 Weave neumorphic（不透明蓝灰底 + 凸起/内凹双向软阴影），
   设计稿改成磨砂玻璃（半透明白面 + backdrop blur + 顶部高光 + 冷蓝紫渐变）。

   ⚠ --neu-* 这套名字【刻意保留、只重新指向值】：全站约 880 处 var() 读取，
     改名买不到一个像素，还会把「重命名」和「换皮」两件事的回归耦合在一起分不清。
     千川也靠 .qc-body 从 --neu-shadow-* 派生 --qc-*，那条链路要保持完好。

   ⚠ 设计稿全程用 oklch()。这里【一律写换算好的 sRGB】：国内大量 Chromium 分支
     （360 / QQ 浏览器）版本落后，遇到 oklch() 会把【整条声明】丢掉；而自定义属性
     里的颜色不参与解析校验（存的是 token 流），所以 var() 兜底在这里根本不生效。
     每个值后面注了原始 oklch，方便回溯。

   ⚠ 两条不许动的红线，改之前先看 backend/test/qianchuan-visual-theme.test.js：
     ① --neu-bg-1 / --panel 必须【不透明】—— .modal-card 坐在 rgba(42,58,88,.40)
        遮罩上，一旦半透明，全站弹窗/下拉/菜单/toast 会变深底配深字（约 3:1 读不了）。
        玻璃的半透明走 --glass-fill 按需下发，不走这两个。
     ② --neu-shadow-*-light 必须是 transparent —— 那是新拟物「凸起」的左上白半边，
        清零它，全站 180 多条双向阴影一次性失去浮雕感。这是整次换肤的总开关。
   ============================================================ */
:root {
  color-scheme: light;

  /* ---------- 页面底：三层 mesh 渐变（设计稿 #5a 的 background） ---------- */
  --page-bg:
    radial-gradient(ellipse 1000px 600px at 10% 0%,   #dceaf8, transparent 60%),  /* oklch(93% .025 250) */
    radial-gradient(ellipse 900px 700px at 100% 15%,  #d1e4f4, transparent 55%),  /* oklch(91% .03  245) */
    radial-gradient(ellipse 1000px 800px at 30% 100%, #d6e7f4, transparent 60%),  /* oklch(92% .025 240) */
    #f7f9fa;                                                                      /* oklch(98% .003 250) */
  --page-bg-flat: #f7f9fc;   /* 不支持多层渐变时的兜底，也用于必须不透明的面 */

  /* ---------- 玻璃配方 ---------- */
  --glass-fill:        rgba(255,255,255,0.20);  /* T2 常规玻璃面，压在页面 mesh 上 */
  --glass-fill-hi:     rgba(255,255,255,0.28);  /* hover / 强调 / featured */
  --glass-fill-strong: rgba(255,255,255,0.72);  /* T2F 浮层：坐在遮罩上，必须更实 */
  --glass-fill-inset:  rgba(255,255,255,0.28);  /* T3 玻璃【内部】的输入框/行，永不加 blur */
  --glass-border:      rgba(255,255,255,0.38);
  --glass-border-hi:   rgba(255,255,255,0.50);
  /* ⚠ 表单控件【不能】用上面那条白边：设计稿的输入框都压在彩色 mesh 上，白边看得见；
     本站大量输入框在近白的卡片/弹窗里，白边等于没有边框，用户找不到输入区在哪。
     这里单独给一条冷灰实线，只用于输入框/下拉/文本域。 */
  --glass-field-border: rgba(120,130,170,0.36);
  --glass-blur:        blur(16px) saturate(1.6);
  --glass-blur-lg:     blur(22px) saturate(1.7);
  --glass-shadow:      0 8px 20px rgba(30,40,80,0.10),  inset 0 1px 0 rgba(255,255,255,0.30);
  --glass-shadow-lg:   0 20px 44px rgba(30,40,80,0.16), inset 0 1px 0 rgba(255,255,255,0.40);
  --glass-shadow-sm:   0 4px 12px rgba(30,40,80,0.08),  inset 0 1px 0 rgba(255,255,255,0.25);
  /* 「玻璃棱」：一条冷灰实线 + 一条白高光，合起来才有厚度（设计稿的分栏边） */
  --glass-divider-line:  rgba(120,130,170,0.28);
  --glass-divider-light: rgba(255,255,255,0.50);

  /* ---------- 品牌 ---------- */
  --brand-grad:      linear-gradient(135deg, #886bee, #2885ef);  /* oklch(62% .19 290) → (62% .18 255) */
  --brand-grad-soft: linear-gradient(135deg, #9c76f3, #2885ef);  /* oklch(66% .18 295) → (62% .18 255) */
  --brand-shadow:    0 10px 26px rgba(88,116,234,0.40);          /* oklch(60% .18 270 / .4) */
  --brand-shadow-sm: 0 6px 16px  rgba(88,116,234,0.35);
  /* h1 渐变裁字。⚠ 四个停靠点全部实测过对比度（在近白 mesh 上，白底 L=0.944）：
     14.2 / 5.4 / 5.0 / 4.6 —— 都过 AA 正文线。设计稿原来的尾段 #35c6e6→#66e6bf 只有
     1.9:1，中文标题第二行正好落在那一段，肉眼就是「褪色」。保留 靛→蓝→青→墨绿 的走向，
     只把亮度整体压下来。改这四个色一定要重新量，别凭感觉调。 */
  --hero-title-grad: linear-gradient(100deg, #1a1a6b 0%, #2a63c4 45%, #16749a 76%, #16806a 100%);

  /* ---------- 遗留扁平套（body / .card / .panel / 千川经 .qc-body 重映射后用） ---------- */
  --bg: var(--page-bg-flat);
  --bg-2: rgba(255,255,255,0.35);
  --panel: #f8fafd;                 /* ⚠ 必须不透明，见文件头红线 ① */
  --text: #1a2029;                  /* oklch(24% .02 260) */
  --muted: #414957;                 /* 与 --neu-text-secondary 同步加深，见下 */
  --line: rgba(120,130,170,0.22);
  --line-strong: rgba(120,130,170,0.34);
  --brand: #5d53ae;                 /* oklch(50% .14 285)，见下方对比度说明 */
  --brand-2: #2885ef;               /* oklch(62% .18 255) */
  --brand-soft: rgba(136,107,238,0.12);
  --shadow: var(--glass-shadow);
  --shadow-hover: var(--glass-shadow-lg);

  /* 项目卡片 */
  --project-card-min-width: 360px;
  --project-card-min-height: 220px;
  --project-card-padding: 28px;
  --project-card-gap: 32px;

  /* ---------- 容器 ----------
     2026-08-03：原来四处版心各写各的数字（首页/定价 1440、个人中心/积分/后台 1400、项目页 2000），
     最大化后左右各空 240px+。设计稿本身【没有版心上限】（.dc.html 里的 1200px 是画板尺寸，
     #5a 中唯一的 max-width 是 h1 的 820 和副标题的 520 两个可读行宽），所以统一到一个
     「大到 1920/2560 上等同满屏、只挡超宽屏」的值，可读行宽交给各自的正文元素去限。 */
  --app-max-width: 2560px;                  /* 2K 及以下＝完全满屏；只在超宽屏/4K 上才开始留白 */
  --app-gutter: clamp(20px, 3.2vw, 72px);   /* 版心左右留白；满宽出血靠 calc(-1 * 它) 自洽 */
  --projects-container-padding: 32px 64px;

  /* ---------- --neu-*：名字沿用，值全部指向玻璃体系 ---------- */
  --neu-bg-1: #f8fafd;              /* ⚠ 不透明，见红线 ①。分错场景时它退化成「白卡片」，朴素但不坏 */
  --neu-bg-2: #eef2f9;
  --neu-shadow-raised-light: transparent;      /* ⚠ 红线 ②：换肤总开关 */
  --neu-shadow-raised-dark:  rgba(30,40,80,0.10);
  --neu-shadow-inset-light:  transparent;      /* ⚠ 红线 ② */
  --neu-shadow-inset-dark:   rgba(120,130,170,0.14);
  --neu-brand-start: #9c76f3;       /* oklch(66% .18 295) */
  --neu-brand-end:   #2885ef;       /* oklch(62% .18 255) */
  --neu-text-primary:   #1a2029;    /* oklch(24% .02 260)   13.2:1 */
  /* ⚠ 设计稿的弱文本是 oklch(55%)=#6b727e，实测在最深的 mesh 上只有 3.9:1 ——
     本站满屏是 12–12.5px 的说明小字，那样不达 AA。这两档已经比设计稿深过一次；
     2026-08-03 用户反馈「颜色深度不够」，再各深一档（只往深走，对比度纯增益）。 */
  --neu-text-secondary: #414957;    /* oklch(40% .02 260)    8.0:1 */
  --neu-text-muted:     #4f5661;    /* oklch(45% .02 260)    6.0:1 */
  /* ⚠ 同理：设计稿的强调色 oklch(55% .13 285)=#6b64ba 只有 4.1:1，链接文字不达标 ⇒ 收到 50% */
  --neu-accent:         #5d53ae;    /* oklch(50% .14 285)    5.1:1 */
  --neu-line: rgba(120,130,170,0.20);
  --neu-text-hero: #0f1624;         /* oklch(20% .03 265)，h1 渐变不被支持时的兜底色 */
  /* 功能卡 4 色渐变：取自设计稿自己的图标渐变（定价页两个 plan 图标 / 积分图标 / 头像） */
  --neu-grad-blue-start:  #3792fd;  --neu-grad-blue-end:  #009bd9;  /* oklch(66% .18 255)→(64% .16 230) */
  --neu-grad-teal-start:  #00bdbe;  --neu-grad-teal-end:  #00b393;  /* oklch(72% .13 195)→(68% .14 175) */
  --neu-grad-amber-start: #eb883b;  --neu-grad-amber-end: #ea6c5a;  /* oklch(72% .15 55) →(68% .16 30)  */
  --neu-grad-rose-start:  #ea6878;  --neu-grad-rose-end:  #d94b78;  /* oklch(68% .16 15) →(62% .18 5)   */
}
* { box-sizing: border-box; }
html, body { min-height: 100%; }
body {
  margin: 0;
  font-family: 'Noto Sans SC', system-ui, -apple-system, BlinkMacSystemFont, "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", sans-serif;
  color: var(--text);
  background: var(--page-bg);
  background-attachment: scroll;
  /* ⚠ 不要用 background-attachment: fixed —— 移动端 Safari / Chrome-Android 上它会把整页
     提成一个合成层，滚动直接掉帧。长页面上 mesh 被拉伸是可接受的代价。
     ⚠ 也不要给 body 加 backdrop-filter：那会让所有 position:fixed 后代改以 body 为包含块。 */
}
button, input, textarea, pre { font: inherit; }
button {
  border: 0;
  cursor: pointer;
  transition: transform .15s ease, opacity .15s ease, background .15s ease, border-color .15s ease;
}
button:hover { transform: translateY(-1px); }
button:active { transform: translateY(0); }
/* ⚠ width: 100% 是历史包袱，【不要删】：文本框 / textarea / range 滑块的整块布局都建立在它之上，
     去掉会让全站表单塌成 auto 宽。
   ⚠ 但 checkbox / radio 没有「100% 宽」的语义，被它撑成扁白条（实测 20×13，本该 13×13）。
     历史做法是**每冒出一处就本地补一条 override**（.adm-col-perm / .adm-audience-list 2026-07-10 /
     .qc-check-inline + .qc-mat-chip 2026-07-26·27 / .qc-colfilter-pop / .qc-sess-pick 共六处），
     仍然复发 —— 第五次是 2026-08-03 后台用户表的 .user-select-check / .user-select-all。
     所以这次在源头把这两个 type 排除掉，不再打第七个补丁。

   为什么用 `:where(:not(…))` 而不是「另起一条 input[type=checkbox]{width:auto}」：
     后者的 specificity 是 (0,1,1)，会**反过来盖掉** .adm-toggle(0,1,0) 那种
     appearance:none 的自定义开关（实测它被压成 2×24，本该 44×24）。
     `:where()` 贡献 0 specificity ⇒ 这条规则仍然是原来的 (0,0,1)，
     排序、与后面所有覆写的胜负关系【一个字都没变】，只是不再命中这两个 type。
   ⚠ 别把 range 一起排除：.ff-* 滑块 appearance:none 后的行程算法依赖 width:100%。 */
input:where(:not([type="checkbox"]):not([type="radio"])), textarea, pre {
  width: 100%;
  border-radius: 16px;
  border: 1px solid var(--glass-field-border);
  background: var(--glass-fill-inset);
  color: var(--text);
  padding: 12px 14px;
}
input::placeholder, textarea::placeholder { color: var(--neu-text-muted); }
textarea { resize: vertical; }
html, body, .app-shell, .workspace-layout, .main-panel, .main-view, .chat-panel { min-height: 0; }
pre { overflow: auto; white-space: pre-wrap; }
.hidden { display: none !important; }

/* ============================================================
   首页 · 磨砂玻璃（1:1 对齐 AquaHorse Homepage Options.dc.html 的 #5a）
   ============================================================
   构图/配色/层级 1:1 照抄设计稿；⚠ 设计稿是【左对齐】的（旧版是居中）。
   ⚠ 但【字号不能照抄】：设计稿是 1200px 画板，本站是满屏（--app-max-width 2200px），
     照抄的死数字在 1920/2560 上会整体显小。所以标题/正文一律改成 clamp(…vw…) 流体值，
     可读行宽由 .landing-title / .landing-subtitle 自己的 max-width 限住。 */
.landing-screen {
  min-height: 100vh;
  background: var(--page-bg);
  color: var(--neu-text-primary);
  overflow-y: auto;
  font-family: 'Noto Sans SC', system-ui, -apple-system, BlinkMacSystemFont, "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", sans-serif;
}
.landing-container { max-width: var(--app-max-width); margin: 0 auto; padding-inline: var(--app-gutter); }

/* --- 导航 + hero 共用的 mesh 底图带（.dc.html:43）---
   负 margin + 等量 padding = 满宽出血，同时保持内容仍在版心里。两边都读 --app-gutter，
   所以断点里只改容器 padding 就够了，不需要再手动同步这里的负 margin。 */
.landing-hero-band {
  position: relative;
  margin-inline: calc(-1 * var(--app-gutter));
  padding-inline: var(--app-gutter);
  background-image: url('/img/landing-hero-mesh.webp');
  background-size: cover;
  background-position: center top;
  overflow: hidden;
}
/* ⚠ 底图右半是饱和蓝绿（L 65–75%），文案压上去只有约 3.2:1。
   设计稿靠 max-width:520px 把文案锁在左侧白区躲开；窄视口时彩色区会滑到文字底下，
   所以这里再叠一层从左到右的白色压光，保证任何宽度下文案都在浅底上。 */
.landing-hero-band::before {
  content: '';
  position: absolute; inset: 0;
  /* 宽屏时文案本来就落在左侧浅区，压光只要很轻；窄屏时彩色区会滑过来，下面的
     @media 会把 background-position 挪到 left top，同时把这层压重。 */
  background: linear-gradient(to right, rgba(255,255,255,.28), rgba(255,255,255,0) 55%);
  pointer-events: none;
}
.landing-hero-band > * { position: relative; z-index: 1; }

/* --- 顶栏 --- */
.landing-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 24px 0; margin-bottom: 0;
}
.landing-brand { display: flex; align-items: center; gap: 12px; }
.landing-brand-name { font-size: 22px; font-weight: 700; color: var(--neu-text-primary); letter-spacing: .3px; }

.landing-nav-links { display: flex; gap: 32px; align-items: center; }
.landing-nav-links .nav-link {
  font-size: 15px; font-weight: 500; color: var(--neu-text-secondary);
  text-decoration: none; padding: 8px 4px; cursor: pointer;
  transition: color .2s ease;
}
.landing-nav-links .nav-link:hover { color: var(--neu-accent); }

.landing-nav { display: flex; gap: 10px; align-items: center; }
.landing-auth-actions { display: flex; gap: 10px; align-items: center; }
/* 设计稿的「登录」是纯文字，不是按钮（.dc.html:50） */
.landing-login-link {
  background: none; border: none; box-shadow: none;
  font-size: 15px; color: var(--neu-text-secondary);
  cursor: pointer; padding: 9px 8px;
}
.landing-login-link:hover { color: var(--neu-accent); transform: none; }

/* --- Hero --- */
.landing-hero { text-align: left; padding: 70px 0 60px; }

.landing-version-pill {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 16px; border-radius: 100px; margin-bottom: 28px;
  font-size: 14px; font-weight: 500; color: #384768;  /* oklch(40% .06 265) */
  white-space: nowrap;
}
.landing-version-pill i { font-size: 15px; }

/* h1 用渐变裁字（.dc.html:57）。
   ⚠ 这里踩过坑：改版前第 197 行写着 `background:none; -webkit-text-fill-color:currentColor`，
     那是上一次渐变文字尝试失败后的【撤销】。所以必须配 @supports 兜底 —— 一旦不支持
     background-clip:text，transparent 的 fill 会让整个 h1 变成隐形。 */
/* ⚠ 设计稿的 72px / 820px 是照 1200px 画板量的死数字；本站满屏后必须跟着视口长，
   否则在 1920/2560 上整块 hero 会显小。下面几处同理，一律改成流体值。 */
.landing-title {
  font-size: clamp(40px, 4.6vw, 96px); font-weight: 800;
  margin: 0 0 26px; line-height: 1.1; letter-spacing: -1.5px;
  /* ⚠ width:fit-content 是必须的，不是装饰：background-clip:text 是按【元素盒宽】铺渐变的，
     h1 作为块级元素会占满 max-width，于是字只吃到渐变最左边一小段、四个停靠点看不出来。
     收成 fit-content 后渐变正好铺在字上。 */
  width: fit-content;
  max-width: min(1100px, 60vw);
  color: var(--neu-text-hero);
  background-image: var(--hero-title-grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .landing-title {
    background-image: none;
    -webkit-text-fill-color: currentColor;
    color: var(--neu-text-hero);
  }
}
.landing-subtitle {
  font-size: clamp(17px, 1.25vw, 24px); color: var(--neu-text-secondary);
  max-width: min(720px, 42vw); margin: 0 0 34px; line-height: 1.6;
}

.landing-cta { display: flex; justify-content: flex-start; gap: 14px; align-items: center; flex-wrap: wrap; }
.large-btn { padding: 15px 32px; font-size: 16px; font-weight: 600; }

/* --- 分节标题：设计稿是「小号弱色 eyebrow 在上、大号标题在下」，
   和旧版的 .section-title/.section-subtitle 正好相反。
   ⚠ 那两个类与定价页共用，不能改语义 ⇒ 这里新增两个类，旧的原样留给定价页。 --- */
.section-eyebrow { font-size: clamp(14px, .85vw, 17px); color: var(--neu-text-muted); margin-bottom: 10px; text-align: left; }
.section-heading {
  font-size: clamp(26px, 2.1vw, 42px); font-weight: 700; letter-spacing: -.5px;
  color: var(--neu-text-primary); margin: 0 0 40px; text-align: left;
}
.section-title { font-size: clamp(26px, 2.1vw, 42px); font-weight: 700; text-align: center; margin: 70px 0 10px; color: var(--neu-text-hero); }
.section-subtitle { font-size: clamp(15px, 1.05vw, 19px); color: var(--neu-text-secondary); text-align: center; margin: 0 0 44px; }

/* --- 核心功能 --- */
.landing-features { padding: 70px 0 60px; }
.features-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px;
  margin: 0;
}
.feature-card {
  border-radius: 14px; padding: 24px; text-align: left;
  transition: box-shadow .2s ease, background .2s ease;
}
/* 设计稿四块图标用的是【同一条】品牌渐变（.dc.html:71/76/81/86），不是旧版的蓝/青/琥珀/玫瑰四色。
   方块里保留 Tabler 图标：设计稿画的是空方块，那是设计工具没有图标系统所致。 */
.feature-icon {
  width: 44px; height: 44px; border-radius: 11px; margin: 0 0 16px;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 21px;
  background: var(--brand-grad-soft);
}
.feature-card h3 { margin: 0 0 8px; font-size: clamp(17px, 1.05vw, 20px); font-weight: 700; color: var(--neu-text-primary); }
.feature-card p { margin: 0; color: var(--neu-text-secondary); font-size: clamp(14px, .85vw, 16px); line-height: 1.6; }

/* --- 案例展示：设计稿把原来的动态横向滚动换成【一整张满宽出血的合成大图】(.dc.html:93-101) ---
   顶部 200px 渐隐把图融进页面；底部是硬边直接顶到页脚分隔线 —— 设计稿就只处理了顶部，照做。
   （实测该图上下边缘都不是白的：顶 rgb(124,159,183)、底 rgb(68,104,130)。） */
.landing-cases { padding: 80px 0 0; }
.cases-composite {
  position: relative;
  line-height: 0;
  margin-inline: calc(-1 * var(--app-gutter));
}
.cases-composite img { width: 100%; height: auto; display: block; }
.cases-composite::before {
  content: '';
  position: absolute; top: 0; left: 0; right: 0; height: 200px;
  background: linear-gradient(to bottom, #f4f9fe, rgba(255,255,255,0));  /* oklch(98% .008 250) */
  pointer-events: none;
}


/* --- 页脚：设计稿是左对齐、紧贴案例大图（.dc.html:104），没有 margin-top --- */
.landing-footer {
  text-align: left; padding: 28px 0; color: var(--neu-text-muted);
  font-size: 15px; border-top: 1px solid var(--glass-border); margin-top: 0;
}
.landing-footer p { margin: 0; }
/* 定价页复用 .landing-footer，但它没有满宽大图，仍居中更好看 */
.pricing-screen .landing-footer { text-align: center; }

/* --- 定价页（独立全屏，与 landing 同一 neumorphic 体系）--- */
.pricing-screen {
  min-height: 100vh;
  background: var(--page-bg);
  color: var(--neu-text-primary);
  overflow-y: auto;
  font-family: 'Noto Sans SC', system-ui, -apple-system, BlinkMacSystemFont, "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", sans-serif;
}
.pricing-screen .back-btn {
  background: var(--neu-bg-1); border: 0; color: var(--neu-text-secondary);
  padding: 9px 18px; border-radius: 12px; margin: 0; font-size: 14px; cursor: pointer;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark), -3px -3px 6px var(--neu-shadow-raised-light);
  transition: color .2s ease, box-shadow .15s ease;
}
.pricing-screen .back-btn:hover {
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 5px var(--neu-shadow-inset-dark), inset -2px -2px 5px var(--neu-shadow-inset-light);
}
.pricing-hero { text-align: center; padding: 24px 20px 6px; }
.pricing-hero .section-title { margin-top: 20px; }

.pricing-grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 380px));
  gap: 28px; justify-content: center; align-items: stretch;
  max-width: 860px; margin: 34px auto 40px; padding: 0 20px;
}
.pricing-card {
  position: relative;
  background: var(--neu-bg-1);
  border-radius: 20px; padding: 36px 30px;
  display: flex; flex-direction: column;
  box-shadow: 6px 6px 14px var(--neu-shadow-raised-dark), -6px -6px 14px var(--neu-shadow-raised-light);
  transition: transform .2s ease, box-shadow .2s ease;
}
.pricing-card:hover {
  transform: translateY(-3px);
  box-shadow: 8px 8px 18px var(--neu-shadow-raised-dark), -8px -8px 18px var(--neu-shadow-raised-light);
}
.pricing-card--featured { outline: 1.5px solid var(--neu-accent); outline-offset: -1.5px; }
.pricing-badge {
  position: absolute; top: 18px; right: 18px;
  padding: 5px 12px; border-radius: 20px; font-size: 12px; font-weight: 600; color: #fff;
  background: linear-gradient(145deg, var(--neu-grad-amber-start), var(--neu-grad-amber-end));
  box-shadow: 0 3px 8px rgba(216,152,64,0.35);
}
.pricing-card-head { text-align: center; margin-bottom: 14px; }
.pricing-plan-icon {
  width: 56px; height: 56px; border-radius: 15px; margin: 0 auto 16px;
  display: flex; align-items: center; justify-content: center; color: #fff; font-size: 27px;
}

/* ⚠ .feature-grad-* 与 .landing-brand-icon 首页改版后不再使用，但【定价页还在用】
   （index.html 的 .pricing-plan-icon.feature-grad-blue / -amber，以及定价页顶栏的品牌图标）。
   千川顶栏的 .qc-brandmark 也是照着 .landing-brand-icon 抄的。所以这几条不能跟着首页一起删。
   取值来自设计稿自己的图标渐变（.dc.html:178/192 的两个 plan 图标）。 */
.landing-brand-icon {
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--brand-grad-soft);
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 20px; flex: none;
  box-shadow: var(--brand-shadow-sm);
}
.feature-grad-blue  { background: linear-gradient(145deg, var(--neu-grad-blue-start),  var(--neu-grad-blue-end)); }
.feature-grad-teal  { background: linear-gradient(145deg, var(--neu-grad-teal-start),  var(--neu-grad-teal-end)); }
.feature-grad-amber { background: linear-gradient(145deg, var(--neu-grad-amber-start), var(--neu-grad-amber-end)); }
.feature-grad-rose  { background: linear-gradient(145deg, var(--neu-grad-rose-start),  var(--neu-grad-rose-end)); }
.pricing-plan-name { margin: 0 0 6px; font-size: 22px; font-weight: 700; color: var(--neu-text-hero); }
.pricing-plan-tagline { margin: 0; font-size: 15px; color: var(--neu-text-muted); }
.pricing-price {
  text-align: center; margin: 8px 0 22px; padding-bottom: 22px;
  border-bottom: 1px solid var(--neu-line);
}
.pricing-amount { font-size: 40px; font-weight: 800; color: var(--neu-text-primary); letter-spacing: -0.02em; }
.pricing-period { font-size: 15px; color: var(--neu-text-muted); margin-left: 6px; }
.pricing-features { list-style: none; margin: 0 0 28px; padding: 0; flex: 1; }
.pricing-features li {
  display: flex; align-items: flex-start; gap: 10px;
  font-size: 15.5px; color: var(--neu-text-secondary); line-height: 1.6; padding: 9px 0;
}
.pricing-features li i { color: var(--neu-accent); font-size: 18px; margin-top: 1px; flex-shrink: 0; }
.pricing-cta { width: 100%; justify-content: center; }
@media (max-width: 760px) {
  .pricing-grid { grid-template-columns: minmax(0, 400px); }
}

/* --- Landing / 定价 内的 primary / ghost 按钮 neumorphic 化（仅作用域内）--- */
.landing-screen .primary-btn,
.pricing-screen .primary-btn {
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  color: #fff; font-weight: 600; font-size: 14px;
  padding: 12px 24px; border-radius: 14px; border: 0;
  display: inline-flex; align-items: center; gap: 8px;
  box-shadow: 4px 4px 10px rgba(40,133,239,0.35), -4px -4px 10px var(--neu-shadow-raised-light);
  transition: box-shadow .15s ease, transform .15s ease;
}
.landing-screen .primary-btn:hover,
.pricing-screen .primary-btn:hover {
  box-shadow: inset 3px 3px 6px rgba(60,90,170,0.35), inset -3px -3px 6px rgba(255,255,255,0.25);
  transform: translateY(0);
}
.landing-screen .ghost-btn {
  background: var(--neu-bg-1); color: var(--neu-accent);
  font-weight: 600; font-size: 14px;
  padding: 12px 24px; border-radius: 14px; border: 0;
  text-decoration: none; display: inline-flex; align-items: center; gap: 8px;
  box-shadow: 4px 4px 10px var(--neu-shadow-raised-dark), -4px -4px 10px var(--neu-shadow-raised-light);
  transition: box-shadow .15s ease, transform .15s ease;
}
.landing-screen .ghost-btn:hover {
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark), inset -3px -3px 6px var(--neu-shadow-inset-light);
}

/* --- 响应式 ---
   出血（.landing-hero-band / .cases-composite）与容器 padding 现在都读 --app-gutter，
   两边天然相等 ⇒ 断点里不需要、也不应该再手写负 margin。
   ⚠ 只剩下正文行宽要管：宽屏用 vw 限，窄屏放开，否则 min(720px,42vw) 会把手机上的副标题掐成一条。 */
@media (max-width: 1024px) {
  .landing-nav-links { display: none; }
  .features-grid { grid-template-columns: repeat(2, 1fr); }
  .landing-title { font-size: clamp(34px, 6vw, 52px); max-width: 100%; }
  .landing-subtitle { font-size: 17px; max-width: 560px; }
  /* 窄屏时 mesh 的饱和蓝绿区会滑到文案底下 ⇒ 把图挪到左上，并加重压光 */
  .landing-hero-band { background-position: left top; }
  .landing-hero-band::before { background: linear-gradient(to right, rgba(255,255,255,.55), rgba(255,255,255,.15) 80%); }
}
@media (max-width: 768px) {
  .landing-hero { padding: 40px 0 36px; }
  .landing-features { padding: 48px 0 40px; }
  .landing-cases { padding: 48px 0 0; }
  .landing-title { font-size: clamp(30px, 8vw, 42px); }
  .landing-subtitle { font-size: 16px; max-width: 100%; }
  .features-grid { grid-template-columns: 1fr; }
  .section-title, .section-heading { font-size: 25px; }
  .landing-hero-band::before { background: linear-gradient(to right, rgba(255,255,255,.62), rgba(255,255,255,.28) 80%); }
}

/* ============================================================
   Locked Feature Modal · Neumorphic
   ============================================================ */
.modal-overlay {
  position: fixed; inset: 0; z-index: 3000;
  background: rgba(42,58,88,0.40);
  display: flex; align-items: center; justify-content: center;
  animation: modal-fade-in .2s ease-out;
}
.modal-overlay.hidden { display: none; }
.modal-card {
  width: 360px; max-width: calc(100% - 32px);
  padding: 36px 32px 28px; border-radius: 22px;
  background: var(--neu-bg-1); text-align: center;
  box-shadow: 8px 8px 20px var(--neu-shadow-raised-dark), -8px -8px 20px var(--neu-shadow-raised-light);
  animation: modal-pop-in .25s cubic-bezier(.2,.9,.3,1);
}
.modal-icon {
  width: 56px; height: 56px; border-radius: 50%; margin: 0 auto 18px;
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  color: #fff; font-size: 24px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 4px 4px 10px rgba(40,133,239,0.40), -4px -4px 10px var(--neu-shadow-raised-light);
}
.modal-title { margin: 0 0 8px; font-size: 18px; font-weight: 700; color: var(--neu-text-hero); }
.modal-text  { margin: 0 0 22px; font-size: 13px; color: var(--neu-text-secondary); line-height: 1.6; white-space: pre-line; }
.modal-card .primary-btn {
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  color: #fff; font-weight: 600; font-size: 13px;
  padding: 10px 28px; border-radius: 12px; border: 0;
  box-shadow: 4px 4px 10px rgba(40,133,239,0.35), -4px -4px 10px var(--neu-shadow-raised-light);
}
.modal-card .primary-btn:hover {
  box-shadow: inset 3px 3px 6px rgba(60,90,170,0.35), inset -3px -3px 6px rgba(255,255,255,0.25);
}
@keyframes modal-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-pop-in  { from { opacity: 0; transform: scale(.92); } to { opacity: 1; transform: scale(1); } }

/* Auth Screen */
.back-btn { background: transparent; border: 1px solid var(--line); color: var(--muted); padding: 8px 16px; border-radius: 12px; margin-bottom: 16px; font-size: 14px; }
.back-btn:hover { border-color: var(--brand); color: var(--brand); }

.auth-screen { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.auth-card { width: min(460px, 100%); background: var(--panel); border: 1px solid var(--line); border-radius: 28px; box-shadow: var(--shadow); padding: 28px; }
.auth-card h1 { margin: 0 0 18px; }
.auth-tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 16px; }
.auth-tab {
  min-height: 46px;
  border-radius: 14px;
  background: linear-gradient(180deg, rgba(255,255,255,.72), rgba(245,247,250,.92));
  color: var(--muted);
  border: 1px solid rgba(218, 220, 224, 0.9);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.8);
}
.auth-tab.active {
  background: linear-gradient(135deg, rgba(136,107,238,.14), rgba(66,133,244,.24));
  color: var(--brand);
  border-color: rgba(136,107,238,.3);
  box-shadow: 0 8px 18px rgba(136,107,238,.12), inset 0 1px 0 rgba(255,255,255,.85);
}
.auth-tab:hover {
  border-color: rgba(136,107,238,.22);
  color: var(--text);
}
.auth-form { display: none; gap: 12px; }
.auth-form.active { display: grid; }
.auth-error { display: none; margin-bottom: 12px; color: #ffb3b3; background: rgba(255, 107, 107, 0.12); border: 1px solid rgba(255,107,107,.2); border-radius: 14px; padding: 10px 12px; }
.primary-btn, #newSessionBtn, #sendBtn { background: var(--brand); color: white; font-weight: 500; padding: 10px 20px; border-radius: 8px; border: none; font-size: 14px; }
.primary-btn:hover, #newSessionBtn:hover, #sendBtn:hover { background: var(--brand-2); }
.ghost-btn { background: transparent; border: 1px solid var(--line); color: var(--text); padding: 8px 16px; border-radius: 8px; font-size: 13px; display: flex; align-items: center; gap: 6px; }
.ghost-btn:hover { background: var(--bg-2); border-color: var(--line-strong); }
.app-shell { width: 100%; margin: 0; padding: 0; }
.topbar { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 16px; padding: 8px 4px; }
.eyebrow { color: var(--brand); font-size: 12px; text-transform: uppercase; letter-spacing: .12em; margin-bottom: 8px; }
.topbar h1 { margin: 0; font-size: clamp(24px, 4vw, 34px); line-height: 1.08; }
.topbar-sub { margin-top: 8px; color: var(--muted); font-size: 14px; }
.topbar-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; justify-content: flex-end; }
.user-chip { padding: 10px 14px; border-radius: 999px; border: 1px solid var(--line); background: rgba(255,255,255,.04); color: #d8e3ff; }
.mobile-tabs { display: none; grid-template-columns: 1fr 1fr auto; gap: 10px; margin-bottom: 12px; }
.mobile-tab { min-height: 44px; border-radius: 14px; background: rgba(255,255,255,.05); color: var(--muted); border: 1px solid var(--line); padding: 0 14px; }
.mobile-tab.active { color: white; background: linear-gradient(135deg, rgba(255,140,66,.28), rgba(255,167,38,.14)); border-color: rgba(255,140,66,.32); }
.sidebar-backdrop { display: none; position: fixed; inset: 0; background: rgba(2, 6, 16, 0.62); z-index: 20; }
.sidebar-backdrop.active { display: block; }
/* 工作区容器（与样式无关） */
.workspace-layout { display: grid; gap: 0; height: 100vh; max-height: 100vh; background: var(--bg); position: relative; }
/* 样式 1：simple（左 sessions / 中对话框 / 右文件 3 栏） */
.workspace-layout.workspace-style-simple { grid-template-columns: 250px minmax(0, 1fr) 300px; }
.workspace-layout.workspace-style-simple.left-collapsed { grid-template-columns: 0 minmax(0, 1fr) 300px; }
.workspace-layout.workspace-style-simple.right-collapsed { grid-template-columns: 250px minmax(0, 1fr) 0; }
.workspace-layout.workspace-style-simple.both-collapsed { grid-template-columns: 0 minmax(0, 1fr) 0; }
/* 未实现样式（card / storyboard）会被 layout-controller 强制 fallback 到 simple class，此处不需要规则 */

/* 工作区顶部"样式未实现"提示条 */
.layout-stub-banner {
  grid-column: 1 / -1;
  background: #fff3cd;
  color: #856404;
  padding: 6px 14px;
  text-align: center;
  font-size: 13px;
  border-bottom: 1px solid #ffeeba;
  z-index: 2500;
}

/* 工作区顶部导航栏 */
.workspace-navbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 56px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 48px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  z-index: 100;
}

.workspace-navbar-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.navbar-separator {
  color: #999;
  font-size: 14px;
  user-select: none;
}

.project-name-display {
  font-size: 14px;
  font-weight: 500;
  color: #333;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.project-name-display:hover {
  background: #f0f0f0;
}
.project-name-input {
  font-size: 14px;
  font-weight: 500;
  border: 1px solid #4a90d9;
  border-radius: 4px;
  padding: 2px 6px;
  outline: none;
  width: 160px;
}

.nav-link-btn {
  background: none;
  border: none;
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  padding: 8px 16px;
  border-radius: 8px;
}

.nav-link-btn:hover {
  background: var(--bg-2);
}

.workspace-layout .left-panel,
.workspace-layout .center-panel,
.workspace-layout .right-panel {
  margin-top: 56px;
  height: calc(100vh - 56px);
}
.session-input-container { padding: 12px; }
.session-label-input { width: 100%; padding: 9px 12px; border: 1px solid var(--glass-field-border); background: var(--glass-fill-inset); border-radius: 12px; margin-bottom: 8px; font-size: 13px; }
.chat-container { display: flex; flex-direction: column; height: 100%; background: var(--panel); }
.chat-header { border-bottom: 1px solid var(--line); padding: 16px 24px; display: flex; justify-content: space-between; align-items: center; }
.chat-header h2 { margin: 0; font-size: 16px; font-weight: 500; }
.chat-header-actions { display: flex; gap: 8px; }
.chat-log { flex: 1; overflow-y: auto; padding: 16px 24px; display: flex; flex-direction: column; }
.chat-log-inner { display: flex; flex-direction: column; gap: 16px; min-height: min-content; }
.composer { padding: 16px 24px; border-top: 1px solid var(--line); flex-shrink: 0; }
.composer textarea { border-radius: 8px; }
/* ⚠ 不要在这里加 border-bottom：换肤后侧栏内部没有任何横向分隔线了（标题行也不再是卡片），
   单独留一条会变成「上传文件下面那条莫名其妙的细线」。 */
.file-upload-container { padding: 8px; }
.file-upload-btn { width: 100%; justify-content: center; }
.current-path { padding: 8px 12px; font-size: 12px; color: var(--muted); }
.workspace-layout.hidden { display: none; }
.show-panel-btn.hidden { display: none; }

/* 汉堡按钮：在三栏区域顶部，折叠时显示 */
.hamburger-btn {
  position: absolute;
  top: 64px;
  z-index: 10;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px;
  cursor: pointer;
  box-shadow: var(--shadow);
  display: none;
}
.hamburger-btn.visible { display: block; }
.hamburger-btn.left { left: 8px; }
.hamburger-btn.right { right: 8px; }
.hamburger-btn:hover { background: var(--bg-2); }

/* 折叠时为汉堡按钮留出空间 */
.workspace-layout.left-collapsed .center-panel { margin-left: 48px; }
.workspace-layout.right-collapsed .center-panel { margin-right: 48px; }

/* 拖拽调整宽度的分隔条 */
.resize-handle {
  position: absolute;
  /* ⚠ 这里是 0 不是 56px：定位上下文是 .left-panel / .right-panel（下面那条 position: relative），
     而它们自己已经 margin-top: 56px 了。写 56px 会让分栏条顶部 56px 变成拖不动的死区，
     ::before 的 top:50% 也会比真正的中线低 28px。 */
  top: 0;
  bottom: 0;
  width: 4px;
  background: transparent;
  cursor: col-resize;
  z-index: 10;
  transition: background 0.2s;
}
.resize-handle:hover,
.resize-handle.dragging {
  background: var(--brand);
}
.resize-handle.left {
  right: -2px;
}
.resize-handle.right {
  left: -2px;
}
.left-panel, .center-panel, .right-panel { min-height: 0; position: relative; }
.left-panel, .right-panel { background: var(--panel); border-right: 1px solid var(--line); display: flex; flex-direction: column; overflow: hidden; transition: opacity 0.3s ease; }
.right-panel { border-right: none; border-left: 1px solid var(--line); }
.left-panel.collapsed, .right-panel.collapsed { width: 0; opacity: 0; pointer-events: none; }
.panel-header { display: flex; justify-content: space-between; align-items: center; padding: 16px; border-bottom: 1px solid var(--line); background: var(--panel); }
.panel-header h2 { margin: 0; font-size: 15px; font-weight: 500; color: var(--text); }
.toggle-btn { background: none; border: none; color: var(--muted); padding: 4px; cursor: pointer; font-size: 16px; }
.toggle-btn:hover { color: var(--text); }
.center-panel { display: flex; overflow: hidden; background: var(--bg); }
.center-view { display: none; width: 100%; min-height: 0; }
.center-view.active { display: flex; flex-direction: column; }
.nav-rail { background: var(--panel); border-right: 1px solid var(--line); padding: 12px 8px; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.rail-brand { width: 40px; height: 40px; border-radius: 8px; display: grid; place-items: center; font-size: 20px; background: var(--brand-soft); margin-bottom: 12px; }
.rail-btn { width: 100%; min-height: 48px; border-radius: 8px; border: none; background: transparent; color: var(--muted); writing-mode: vertical-rl; text-orientation: mixed; font-weight: 500; font-size: 13px; }
.rail-btn.active { color: var(--brand); background: var(--brand-soft); }
.rail-btn:hover { background: var(--bg-2); }
.sidebar-panel, .main-panel { display: flex; overflow: hidden; }
.sidebar-view, .main-view { display: none; width: 100%; min-height: 0; }
.sidebar-view.active, .main-view.active { display: flex; flex-direction: column; gap: 16px; }
/* ⚠ 这里【不写 backdrop-filter】：--panel 是刻意不透明的（红线 ①），压在不透明底下的 blur
   是纯无效声明，却仍会给 position:fixed 后代造包含块。玻璃在文件末尾终端块里按面下发。 */
.card, .panel { background: var(--panel); border: 1px solid var(--line); border-radius: 24px; box-shadow: var(--shadow); }
.card { padding: 16px; }
.panel { padding: 18px; min-height: 0; }
.fill-card, .full-height { flex: 1; display: flex; flex-direction: column; }
.chat-panel { overflow: hidden; }
/* ⚠ .panel-head（预览/案例视图的标题行）与左右栏的 .panel-header 是两个不同的类，别改混 */
.card-head, .panel-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 14px; padding-bottom: 12px; border-bottom: 1px solid var(--glass-divider-line); }
.mobile-stack { align-items: flex-start; }
h2 { margin: 0; font-size: 18px; }
.label { color: var(--muted); font-size: 12px; margin-bottom: 6px; }
.value { font-size: 15px; font-weight: 600; }
.muted { color: var(--muted); }
.row { display: flex; align-items: center; }
.gap { gap: 10px; }
.stack-mobile { align-items: stretch; }
.actions-wrap { flex-wrap: wrap; }
.status-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin-bottom: 12px; }
.status-badge, .badge-soft, .session-status { display: inline-flex; align-items: center; justify-content: center; min-height: 30px; padding: 0 12px; border-radius: 999px; font-size: 12px; font-weight: 700; }
.status-badge.ok, .session-status.ready { background: rgba(46, 204, 113, 0.15); color: #7ef0a9; border: 1px solid rgba(46, 204, 113, 0.22); }
.status-badge.pending, .session-status.pending { background: rgba(255,255,255,.08); color: #d7dfef; border: 1px solid rgba(255,255,255,.1); }
.session-status.error { background: rgba(255,107,107,.12); color: #ffb3b3; border: 1px solid rgba(255,107,107,.2); }
.badge-soft { background: var(--brand-soft); color: #ffd4b3; }
.details-block { border-top: 1px solid var(--line); padding-top: 12px; }
.details-block summary { cursor: pointer; color: #cfd8ef; font-size: 14px; }
.session-list, .file-list { display: flex; flex-direction: column; gap: 5px; overflow: auto; padding: 8px; flex: 1; }

.file-tabs {
  display: flex;
  border-bottom: 1px solid var(--line);
  margin-bottom: 12px;
  gap: 4px;
}
.file-tab {
  padding: 10px 20px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  color: var(--muted);
  font-size: 14px;
  transition: all 0.2s ease;
}
.file-tab:hover {
  color: var(--text);
  background: var(--bg-2);
  transform: none;
}
.file-tab.active {
  color: var(--brand);
  border-bottom-color: var(--brand);
  font-weight: 500;
}
.file-list-content {
  display: flex;
  flex-direction: column;
  gap: 5px;
  flex: 1;
  overflow: auto;  /* 允许内容滚动 */
}

.file-list-content.grid-mode, .file-list.grid-mode {
  display: grid;
  row-gap: 2px;
  column-gap: 2px;
  grid-template-columns: repeat(auto-fill, 200px);
  justify-content: start;
  align-items: start;
  grid-auto-rows: min-content;
  position: relative;
  align-content: start;  /* 确保网格内容从顶部开始排列 */
  overflow: auto;  /* 允许内容滚动 */
}
.file-list.dragover {
  background: var(--brand-soft);
  border: 2px dashed var(--brand);
  border-radius: 8px;
}
.file-list-content.grid-mode > .file-item:not([data-path]),
.file-list.grid-mode > .file-item:not([data-path]) {
  grid-column: 1 / -1;
}
.file-list-content.grid-mode.small-grid, .file-list.grid-mode.small-grid {
  grid-template-columns: repeat(auto-fill, 200px);
  row-gap: 2px;
  column-gap: 2px;
}
.file-list-content.grid-mode.medium-grid, .file-list.grid-mode.medium-grid {
  grid-template-columns: repeat(auto-fill, 320px);
  row-gap: 2px;
  column-gap: 2px;
}

/* 拖放相关样式 */
.file-item.dragging {
  opacity: 0.5;
  cursor: grabbing;
}

.file-item.drag-over-folder {
  background: var(--brand-soft) !important;
  border: 2px solid var(--brand) !important;
  transform: scale(1.02);
}

.file-item.insert-before,
.file-item.insert-after {
  position: relative;
}

/* 列表模式：上下插入线 */
.file-list-content:not(.grid-mode) .file-item.insert-before::before,
.file-list:not(.grid-mode) .file-item.insert-before::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: -3px;
  height: 3px;
  background: var(--brand);
  border-radius: 2px;
  z-index: 10;
  box-shadow: 0 0 8px var(--brand);
}

.file-list-content:not(.grid-mode) .file-item.insert-after::after,
.file-list:not(.grid-mode) .file-item.insert-after::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 3px;
  background: var(--brand);
  border-radius: 2px;
  z-index: 10;
  box-shadow: 0 0 8px var(--brand);
}

/* 网格模式：左右插入线 */
.file-list-content.grid-mode .file-item.insert-before::before,
.file-list.grid-mode .file-item.insert-before::before {
  content: '';
  position: absolute;
  left: -3px;
  top: 50%;
  transform: translateY(-50%);
  height: 100%;
  width: 3px;
  background: var(--brand);
  border-radius: 2px;
  z-index: 10;
  box-shadow: 0 0 8px var(--brand);
}

.file-list-content.grid-mode .file-item.insert-after::after,
.file-list.grid-mode .file-item.insert-after::after {
  content: '' !important;
  position: absolute !important;
  left: auto !important;
  right: -3px !important;
  top: 50% !important;
  transform: translateY(-50%) !important;
  height: 100% !important;
  width: 3px !important;
  background: var(--brand) !important;
  border-radius: 2px !important;
  z-index: 10 !important;
  box-shadow: 0 0 8px var(--brand) !important;
}

.file-list.dragging-active,
.file-list-content.dragging-active {
  user-select: none;
  -webkit-user-select: none;
}

.setting-item {
  margin-bottom: 20px;
}
.setting-item label {
  display: block;
  font-weight: 500;
  margin-bottom: 8px;
  color: var(--text);
}
.form-select {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #ffffff;
  color: var(--text);
  font-size: 14px;
  cursor: pointer;
}
.setting-hint {
  margin-top: 6px;
  font-size: 13px;
  color: var(--muted);
}

.session-item, .file-item { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 12px; text-align: left; padding: 10px 12px; border-radius: 8px; border: none; background: transparent; color: var(--text); transition: background 0.15s; }
.session-item:hover, .file-item:hover { background: var(--bg-2); }
.session-item.active { background: var(--brand-soft); color: var(--brand); }
.file-item.selected { background: var(--brand-soft) !important; border: 1px solid var(--brand); }
.file-item.selected:hover { background: rgba(136,107,238, 0.15) !important; }
.file-item.drag-over { background: var(--brand-soft) !important; border: 2px dashed var(--brand) !important; }
.session-main { min-width: 0; display: flex; flex-direction: column; gap: 4px; flex: 1; }
.session-meta { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.session-title, .file-item .name { font-weight: 700; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.session-sub { color: var(--muted); font-size: 13px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.session-row { position: relative; }
.session-more-btn { background: none; border: none; color: var(--muted); font-size: 18px; cursor: pointer; padding: 4px 8px; border-radius: 4px; line-height: 1; }
.session-more-btn:hover { background: var(--bg-2); color: var(--fg); }
.session-context-menu {
  position: fixed;
  z-index: 9999;
  background: var(--neu-bg-1);
  border: 0;
  border-radius: 10px;
  padding: 6px;
  min-width: 120px;
  box-shadow: 6px 6px 14px var(--neu-shadow-raised-dark),
              -6px -6px 14px var(--neu-shadow-raised-light);
}
.session-menu-item {
  display: block;
  width: 100%;
  padding: 8px 12px;
  border: none;
  background: none;
  color: var(--neu-text-primary);
  font-size: 13px;
  text-align: left;
  border-radius: 6px;
  cursor: pointer;
}
.session-menu-item:hover { background: rgba(136,107,238, 0.10); }
.session-menu-item.danger { color: #d04840; }
.session-menu-item.danger:hover { background: rgba(208, 72, 64, 0.08); }
.chat-log { flex: 1; min-height: 0; height: 100%; overflow-y: auto; overflow-x: hidden; padding: 16px 6px 10px; display: flex; flex-direction: column; gap: 14px; scrollbar-gutter: stable; scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.15) transparent; }
.chat-log::-webkit-scrollbar { width: 6px; }
.chat-log::-webkit-scrollbar-track { background: transparent; }
.chat-log::-webkit-scrollbar-thumb { background: rgba(120,130,170,0.35); border-radius: 999px; }
.chat-log::-webkit-scrollbar-thumb:hover { background: rgba(120,130,170,0.55); }
.msg-row { display: flex; margin-bottom: 0; }
.msg-row.user { justify-content: flex-end; }
.msg-row.assistant { justify-content: flex-start; }
/* ⚠ 暗色主题残留：原来是 rgba(255,255,255,.08) 底 + var(--text-secondary) 字，而
   --text-secondary 全站【没有定义】⇒ 走兜底 #aaa，在浅底上约 2.3:1；hover 更是把字变成 #fff，
   整颗按钮当场隐形。改成和 .ghost-btn 一致的玻璃药丸。 */
.load-more-btn { display: block; margin: 0 auto 12px; padding: 6px 18px; background: var(--glass-fill-hi); color: var(--neu-text-secondary); border: 1px solid var(--glass-border); border-radius: 999px; font-size: 13px; cursor: pointer; transition: background 0.2s, color 0.2s; }
.load-more-btn:hover { background: var(--glass-fill-strong); color: var(--neu-accent); }
.msg {
  position: relative;
  max-width: min(78%, 860px);
  padding: 12px 16px;
  border-radius: 8px;
  white-space: pre-wrap;
  line-height: 1.6;
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  font-size: 14px;
}
.msg.user {
  background: var(--brand);
  color: white;
  border-color: var(--brand);
  border-bottom-right-radius: 4px;
}
.msg.assistant {
  background: #ffffff;
  border-color: var(--line);
}
.msg.assistant:not(.thinking)::before {
  content: '小图';
  display: block;
  margin-bottom: 6px;
  font-size: 11px;
  letter-spacing: .04em;
  color: #9fb0ff;
  font-weight: 700;
}
.msg.thinking {
  opacity: .94;
  border-style: dashed;
  min-width: 132px;
  color: #d8ceff;
}
.msg.thinking::before {
  content: '小图';
  display: block;
  margin-bottom: 8px;
  font-size: 11px;
  letter-spacing: .04em;
  color: #9fb0ff;
  font-weight: 700;
}
.msg.thinking::after {
  content: '';
  display: inline-block;
  width: 28px;
  height: 8px;
  margin-left: 8px;
  border-radius: 999px;
  vertical-align: middle;
  /* ⚠ 原来是 #cfc4ff（暗色时代）：在 #f8fafd 的助手气泡上约 1.3:1，整段「思考中」动画等于没有 */
  background: radial-gradient(circle, var(--neu-accent) 28%, transparent 30%) 0 50% / 8px 8px repeat-x;
  animation: thinkingDots 1s linear infinite;
}
@keyframes thinkingDots {
  from { background-position: 0 50%; }
  to { background-position: 24px 50%; }
}
.empty-state { height: 100%; min-height: 220px; display: grid; place-items: center; color: var(--muted); text-align: center; padding: 24px; border: 1px dashed var(--line-strong); border-radius: 20px; }
.composer { display: grid; grid-template-columns: 1fr; gap: 8px; }
.composer-row { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: end; }
.context-token-badge { font-size: 12px; color: var(--muted); padding: 2px 10px; border-radius: 10px; background: var(--glass-fill-inset); border: 1px solid var(--glass-border); white-space: nowrap; line-height: 24px; align-self: center; }
.context-token-badge.warn { color: #ff9800; border-color: #ff9800; }
.context-token-badge.crit { color: #ff5252; border-color: #ff5252; }
.msg.assistant.thinking.compacting { background: rgba(80, 160, 255, 0.08); border-left: 3px solid #4a9eff; }
.composer textarea { min-height: 80px; max-height: 200px; resize: vertical; border-radius: 8px; border: 1px solid var(--line); padding: 12px; }
/* 文件预览的四种载体（图片 / PDF / Word / 纯文本）。
   ⚠ 这几处的底色原来是 rgba(255,255,255,.02~.03) —— 那是【暗色主题时代的残留】，
     在浅色页面上等于完全看不见，于是预览区看着就是一块空白的白板。统一走玻璃内层令牌。 */
.image-preview-wrap { display: flex; align-items: center; justify-content: center; min-height: 280px; margin-top: 6px; border: 1px solid var(--glass-border); border-radius: 18px; background: var(--glass-fill-inset); padding: 12px; }
.image-preview { max-width: 100%; max-height: 62vh; object-fit: contain; border-radius: 14px; }
.pdf-preview-wrap { display: flex; flex: 1; min-height: 400px; margin-top: 6px; border: 1px solid var(--glass-border); border-radius: 18px; overflow: hidden; background: var(--glass-fill-inset); }
.pdf-preview { width: 100%; height: 100%; border: none; }
.word-preview-wrap { flex: 1; min-height: 400px; margin-top: 6px; border: 1px solid var(--glass-border); border-radius: 18px; background: var(--glass-fill-inset); overflow: auto; padding: 20px; }
/* mammoth 转出来的是带标题/列表/表格的 HTML，之前只设了 color ⇒ 全靠浏览器默认样式，
   在磨砂底上又黑又挤。这里给一份最小可读排版。 */
.word-preview { max-width: 800px; margin: 0 auto; color: var(--neu-text-primary); line-height: 1.75; font-size: 15px; }
.word-preview h1, .word-preview h2, .word-preview h3 { color: var(--neu-text-hero); line-height: 1.35; margin: 1.4em 0 .6em; }
.word-preview h1 { font-size: 24px; }
.word-preview h2 { font-size: 20px; }
.word-preview h3 { font-size: 17px; }
.word-preview p { margin: 0 0 1em; }
.word-preview ul, .word-preview ol { margin: 0 0 1em; padding-left: 1.6em; }
.word-preview li { margin-bottom: .35em; }
.word-preview table { border-collapse: collapse; width: 100%; margin: 0 0 1em; font-size: 14px; }
.word-preview th, .word-preview td { border: 1px solid var(--glass-divider-line); padding: 8px 10px; text-align: left; }
.word-preview th { background: var(--glass-fill-hi); font-weight: 700; }
.word-preview img { max-width: 100%; height: auto; }
.editor { min-height: 280px; flex: 1; margin-top: 6px; }
.file-item.editing { padding: 6px 10px; }
.file-item.editing .name { flex: 1; display: flex; align-items: center; gap: 6px; }
/* 项目文件里的重命名输入框。⚠ 原来是 rgba(255,255,255,.08) 底 + var(--accent) 边，而
   --accent 全站没有定义 ⇒ 走兜底 #4a90e2，是这一片唯一一处旧品牌蓝。 */
.file-item-input { flex: 1; font: inherit; color: var(--neu-text-primary); background: var(--glass-fill-inset); border: 1px solid var(--glass-field-border); border-radius: 8px; padding: 2px 8px; outline: none; min-width: 0; }
.file-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: rgba(255,255,255,.03);
}
.file-drop-zone {
  position: relative;
  min-height: 260px;
  border-radius: 18px;
  border: 1px dashed transparent;
  transition: border-color .15s ease, background .15s ease;
}
.file-drop-zone.dragover {
  border-color: rgba(124, 92, 255, 0.55);
  background: rgba(124, 92, 255, 0.08);
}
.file-drop-zone.dragover::after {
  content: '拖到这里即可上传';
  position: sticky;
  top: 0;
  display: grid;
  place-items: center;
  min-height: 64px;
  border-radius: 14px;
  background: rgba(10, 13, 20, 0.78);
  color: #d8ceff;
  font-weight: 700;
}
.context-menu {
  position: fixed;
  z-index: 1000;
  min-width: 160px;
  padding: 8px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: var(--shadow-hover);
}
.context-menu button {
  width: 100%;
  text-align: left;
  padding: 10px 12px;
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font-size: 14px;
}
.context-menu button:hover {
  background: var(--bg-2);
}
.file-item.uploading {
  opacity: 0.5;
  cursor: not-allowed;
}
.file-item.uploading:hover {
  transform: none;
}
/* 单图修改中：整项淡化 + 「修改中」角标 */
.file-item.editing { position: relative; }
.file-item.editing .file-thumbnail { opacity: 0.5; }
.file-editing-badge {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 2;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 11px;
  line-height: 1.5;
  color: #fff;
  background: rgba(184, 134, 11, 0.92);
  box-shadow: 0 1px 3px rgba(0,0,0,.25);
  pointer-events: none;
}
/* 文件预览底部：单图修改栏 */
.image-edit-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  /* 提示词框是 3 行高的 textarea ⇒ 按钮贴底才不会浮在半空（同 .composer-row 的 align-items: end）。 */
  align-items: flex-end;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--glass-divider-line);
}
/* 提示词框（textarea，rows=3）。字体与盒模型不用在这写：:132 的 `font: inherit` 与
   :120 的 `* { box-sizing: border-box }` 已经全局管掉了。 */
.image-edit-input {
  flex: 1;
  /* ⚠ 上内边距别回到 11px：textarea 的占位文字距框顶 = padding-top + 行高半铅空 + 字形上沿，
     11~12px 会明显比站内其它输入框（9~11px）偏下。同 .ff-textarea 那条注释。 */
  padding: 9px 14px;
  border-radius: 16px;
  border: 1px solid var(--glass-field-border);
  background: var(--glass-fill-inset);
  color: var(--neu-text-primary);
  font-size: 14px;
  line-height: 1.5;      /* 定住 3 行的实际高度 */
  /* ⚠ 必须显式关掉：全局有 textarea { resize: vertical }（:152），否则右下角会冒出拖拽手柄。 */
  resize: none;
  overflow-y: auto;      /* 超过 3 行在框内滚，改图栏总高不变 */
}
.image-edit-input:disabled { opacity: 0.6; cursor: not-allowed; }
.image-edit-bar .primary-btn { white-space: nowrap; }
/* 参考图行：占满一行、落在提示词输入框上方（.image-edit-bar 已 flex-wrap）。 */
.image-edit-refs { flex-basis: 100%; display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.image-edit-refs:empty { display: none; }
.edit-ref-thumb {
  position: relative;
  width: 56px; height: 56px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--glass-border);
  background: var(--glass-fill-inset);
  flex: 0 0 auto;
}
.edit-ref-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.edit-ref-remove {
  position: absolute; top: 2px; right: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  background: rgba(0,0,0,0.55); color: #fff;
  font-size: 12px; line-height: 1; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}
.edit-ref-count { font-size: 12px; opacity: 0.7; }
.ghost-btn { background: rgba(255,255,255,0.05); color: var(--text); border: 1px solid var(--line); padding: 11px 14px; border-radius: 16px; }
.ghost-btn:hover { background: rgba(255,255,255,0.08); }
.small-btn { padding: 9px 12px; border-radius: 14px; }
@media (max-width: 960px) {
  .app-shell { width: 100%; padding: 12px; }
  .topbar { flex-direction: column; align-items: stretch; gap: 12px; }
  .topbar-actions { justify-content: stretch; }
  .topbar-actions > * { flex: 1; }
  .mobile-tabs { display: grid; }

  /* 手机端：左右面板完全隐藏，中间会话区域占满 */
  .workspace-layout {
    grid-template-columns: 1fr !important;
    min-height: auto;
  }

  /* 左侧会话列表：固定定位，默认隐藏在左侧（折叠状态） */
  .left-panel {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: min(85vw, 320px);
    z-index: 40;
    transform: translateX(-100%);
    transition: transform 0.3s ease;
    border-right: 1px solid var(--line);
    opacity: 1 !important;
    pointer-events: auto !important;
  }

  /* 左侧面板打开时（移除 collapsed 类） */
  .left-panel:not(.collapsed) {
    transform: translateX(0);
  }

  /* 右侧文件面板：固定定位，默认隐藏在右侧（折叠状态） */
  .right-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(85vw, 320px);
    z-index: 40;
    transform: translateX(100%);
    transition: transform 0.3s ease;
    border-left: 1px solid var(--line);
    opacity: 1 !important;
    pointer-events: auto !important;
  }

  /* 右侧面板打开时（移除 collapsed 类） */
  .right-panel:not(.collapsed) {
    transform: translateX(0);
  }

  /* 面板打开时的遮罩层 */
  .workspace-layout::before {
    content: '';
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 35;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
  }

  .workspace-layout:has(.left-panel:not(.collapsed))::before,
  .workspace-layout:has(.right-panel:not(.collapsed))::before {
    opacity: 1;
    pointer-events: auto;
  }

  /* 中间会话区域：始终占满屏幕 */
  .center-panel {
    width: 100% !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
  }

  /* 隐藏折叠按钮（手机端用汉堡菜单） */
  .toggle-btn { display: none; }

  /* 手机端汉堡按钮：固定在屏幕顶部导航栏下方，始终显示 */
  .hamburger-btn {
    display: block !important;
    position: fixed !important;
    top: 64px !important;
    z-index: 50 !important;
    opacity: 1 !important;
    visibility: visible !important;
  }

  .hamburger-btn.left {
    left: 12px !important;
  }

  .hamburger-btn.right {
    right: 12px !important;
  }

  .nav-rail { display: none; }
  .sidebar-panel { position: fixed; top: 0; left: 0; bottom: 0; width: min(88vw, 380px); padding: 12px; z-index: 30; transform: translateX(-104%); transition: transform .2s ease; overflow: auto; }
  .sidebar-panel.mobile-open { transform: translateX(0); }
  .main-panel { min-width: 0; width: 100%; }
  .card, .panel { border-radius: 20px; }
  .composer-row { grid-template-columns: auto 1fr auto; }
  .composer button, #newSessionBtn, .ghost-btn, .primary-btn { min-height: 46px; }
  .msg { max-width: 100%; }
  .msg.user::after { display: none; }
  .status-grid { grid-template-columns: 1fr; }
  .mobile-stack, .card-head { flex-direction: column; align-items: stretch; }
  .file-toolbar { flex-direction: column; align-items: stretch; }
}

/* 项目页面顶部导航栏 */
.projects-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 100%;
  background: var(--bg);
}

.top-navbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 48px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.brand-btn {
  background: none;
  border: none;
  font-size: 18px;
  font-weight: 700;
  color: var(--brand);
  cursor: pointer;
  padding: 8px 0;
}

.brand-btn:hover {
  color: var(--brand-2);
}

/* 页面标题栏 */
.page-title-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px 48px;
  background: var(--bg);
}

.page-title-bar h1 {
  margin: 0;
  font-size: 28px;
  font-weight: 600;
  color: var(--text);
}

.projects-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 24px 48px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}

.projects-header-left h1 {
  margin: 0;
  font-size: 22px;
  font-weight: 500;
  color: var(--text);
}

.projects-header-right {
  display: flex;
  align-items: center;
  gap: 24px;
}

/* 只剩首页(landing)那一处还在用：它里面是「用户名 + 退出图标」两件，药丸把它们归成一组才有意义。
   「我的项目」/ 工作区两条顶栏的 .user-info 已删——积分徽标和公告图标搬走后它只包着一个圆头像，
   药丸就变成套在头像外面的一层多余底板。那边现在是 .user-menu-wrapper 直接坐在导航栏上。 */
.user-info {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px;
  background: var(--bg-2);
  border-radius: 20px;
}

.user-info span {
  font-size: 14px;
  color: var(--text);
}

.token-usage-badge {
  font-size: 12px;
  color: var(--muted);
  padding: 4px 8px;
  background: var(--bg-2);
  border-radius: 8px;
  cursor: help;
}

/* ===== 积分账本卡片（.cd-*） =====
   2026-08-03：独立全屏页 #creditDetailsView 已删，这批卡片改在个人中心的「积分明细」tab 里渲染，
   宿主是 .pc-main。所以只属于旧外壳的那些规则（.credit-badge / .credit-detail-v2 / .cd-topbar /
   .cd-back / .cd-badge / .cd-title / .cd-refresh / .cd-body）一并删了 —— 宽度与留白由 .pc-main 管。 */
.cd-loading,
.cd-error,
.cd-empty {
  text-align: center;
  color: var(--neu-text-muted);
  padding: 40px 0;
  font-size: 14px;
}
.cd-error { color: #c04060; }

.cd-card {
  background: var(--neu-bg-1);
  border-radius: 20px;
  padding: 32px;
  box-shadow: 7px 7px 16px var(--neu-shadow-raised-dark),
              -7px -7px 16px var(--neu-shadow-raised-light);
  margin-bottom: 22px;
}
.cd-card-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 20px;
  font-size: 19px;
  font-weight: 700;
  color: var(--neu-text-hero);
}
.cd-card-icon { font-size: 20px; color: #886bee; }

.cd-stat-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-bottom: 24px;
}
.cd-expiry-note {
  margin: -8px 0 22px;
  padding: 10px 14px;
  border-radius: 10px;
  background: rgba(184, 134, 11, 0.10);
  color: #8a6d0b;
  font-size: 14px;
}
.cd-expiry-note i { margin-right: 4px; }
.cd-stat { padding: 28px 26px; margin-bottom: 0; }
.cd-stat-label {
  font-size: 14px;
  font-weight: 500;
  color: var(--neu-text-muted);
  margin-bottom: 10px;
  letter-spacing: 0.5px;
}
.cd-stat-number { display: flex; align-items: baseline; gap: 8px; }
.cd-stat-value {
  font-size: 34px;
  font-weight: 800;
  color: var(--neu-text-hero);
  line-height: 1.1;
}
.cd-stat-suffix {
  font-size: 16px;
  font-weight: 500;
  color: var(--neu-text-muted);
}

.cd-bd-row {
  display: grid;
  grid-template-columns: 1fr 160px 80px;
  padding: 14px 0;
  border-bottom: 1px solid rgba(120,130,170, 0.10);
  font-size: 15px;
  align-items: center;
}
.cd-bd-row:last-child { border-bottom: 0; }
.cd-bd-name { color: var(--neu-text-primary); font-weight: 500; }
.cd-bd-value { text-align: right; color: var(--neu-text-hero); font-weight: 600; }
.cd-bd-percent { text-align: right; color: var(--neu-text-muted); font-size: 14px; }

/* 我的发放计划 / 我的积分明细（用户端只读视图） */
.cd-pool-note {
  margin: -4px 0 10px;
  padding: 8px 12px;
  border-radius: 10px;
  background: rgba(136,107,238, 0.10);
  color: #3f6ab8;
  font-size: 14px;
}
.cd-pool-note i { margin-right: 4px; }
.cd-plan-row {
  padding: 12px 0;
  border-bottom: 1px solid rgba(120,130,170, 0.10);
}
.cd-plan-row:last-child { border-bottom: 0; }
.cd-plan-main { font-size: 15px; color: var(--neu-text-primary); }
.cd-plan-main strong { color: var(--neu-text-hero); font-weight: 700; }
.cd-plan-meta { margin-top: 4px; font-size: 14px; color: var(--neu-text-muted); }
/* 明细行第三列放的是到期日，比消耗分类的百分比列宽 */
.cd-lot-row { grid-template-columns: 1fr 120px 150px; }
.cd-bd-total {
  border-top: 2px solid rgba(120,130,170, 0.28);
  border-bottom: 0;
  font-weight: 700;
}
.cd-bd-total .cd-bd-value { font-size: 17px; }

/* 最近交易：内置可滚动框 */
.cd-tx-scroll {
  max-height: 480px;
  overflow-y: auto;
  margin: 4px -8px 0;
  padding: 4px 14px 4px 8px;
  border-radius: 14px;
  background: var(--neu-bg-2);
  box-shadow: inset 3px 3px 8px var(--neu-shadow-inset-dark),
              inset -3px -3px 8px var(--neu-shadow-inset-light);
  scrollbar-width: thin;
  scrollbar-color: rgba(136,107,238, 0.45) transparent;
}
.cd-tx-scroll::-webkit-scrollbar { width: 8px; }
.cd-tx-scroll::-webkit-scrollbar-track { background: transparent; margin: 6px 0; }
.cd-tx-scroll::-webkit-scrollbar-thumb {
  background: rgba(136, 107, 238, 0.40);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
.cd-tx-scroll::-webkit-scrollbar-thumb:hover { background: rgba(136, 107, 238, 0.65); background-clip: padding-box; border: 2px solid transparent; }

.cd-tx-list { display: flex; flex-direction: column; }
.cd-tx-row {
  display: grid;
  grid-template-columns: 110px 72px 52px 1fr 140px;
  gap: 14px;
  align-items: center;
  padding: 12px 8px;
  border-bottom: 1px solid rgba(120,130,170, 0.10);
}
.cd-tx-row:last-child { border-bottom: 0; }
.cd-tx-time { font-size: 13px; color: var(--neu-text-muted); }
.cd-tx-tag {
  justify-self: start;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 7px;
  line-height: 1.4;
  letter-spacing: 0.2px;
}
.cd-tx-tag.text {
  background: linear-gradient(135deg, #d8e8f8, #c0d4f0);
  color: #2885ef;
}
.cd-tx-tag.image {
  background: linear-gradient(135deg, #f0e0f0, #e0c8e8);
  color: #9060b0;
}
.cd-tx-model { font-size: 13px; color: var(--neu-text-muted); }
.cd-tx-name {
  font-size: 13px;
  color: var(--neu-text-secondary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cd-tx-amount {
  text-align: right;
  font-size: 14px;
  font-weight: 600;
  color: #e05040;
}

@media (max-width: 960px) {
  .cd-card { padding: 22px; border-radius: 16px; }
}
@media (max-width: 768px) {
  .cd-stat-grid { grid-template-columns: 1fr; gap: 12px; margin-bottom: 16px; }
  .cd-card { padding: 20px; border-radius: 14px; }
  .cd-stat-value { font-size: 28px; }
  .cd-tx-scroll { max-height: 360px; }
  .cd-tx-row {
    grid-template-columns: 84px 64px 1fr 110px;
    gap: 10px;
    padding: 10px 6px;
  }
  .cd-tx-model { display: none; }
  .cd-bd-row { grid-template-columns: 1fr auto auto; gap: 10px; }
}

/* 通用空态 / 错误态（被多处复用，请勿删除） */
.empty-state {
  text-align: center;
  color: var(--muted);
  padding: 40px;
}
.error-message {
  text-align: center;
  color: #ff6b6b;
  padding: 40px;
}

.icon-btn {
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 4px;
  display: flex;
  align-items: center;
  border-radius: 4px;
}

.icon-btn:hover {
  background: var(--bg-2);
  color: var(--text);
}

.projects-container {
  flex: 1;
  overflow-y: auto;
  padding: var(--projects-container-padding);
  width: 100%;
}

.projects-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--project-card-min-width), 1fr));
  gap: var(--project-card-gap);
  width: 100%;
  margin: 0 auto;
}

.project-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: var(--project-card-padding);
  cursor: pointer;
  transition: all 0.2s ease;
  position: relative;
  min-height: var(--project-card-min-height);
  display: flex;
  flex-direction: column;
}

.project-card:hover {
  box-shadow: var(--shadow-hover);
  transform: translateY(-2px);
  border-color: var(--line-strong);
}

.project-card-icon {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28px;
  margin-bottom: 16px;
}

.project-card-title {
  font-size: 18px;
  font-weight: 500;
  color: var(--text);
  margin: 0 0 12px;
  line-height: 1.4;
}

.project-card-description {
  margin: 0 0 16px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.6;
  flex: 1;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.project-card-meta {
  font-size: 13px;
  color: var(--muted);
  margin-top: auto;
}

.project-card-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 12px;
}

.project-card-icon {
  width: 48px;
  height: 48px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  margin-bottom: 12px;
}

.project-card-title {
  font-size: 16px;
  font-weight: 500;
  color: var(--text);
  margin: 0 0 8px;
  line-height: 1.4;
}

.project-card-description {
  margin: 0 0 12px;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
  min-height: 20px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.project-card-meta {
  font-size: 12px;
  color: var(--muted);
}

.project-card-actions {
  display: flex;
  gap: 4px;
  opacity: 0;
  transition: opacity 0.2s;
}

.project-card:hover .project-card-actions {
  opacity: 1;
}

.project-card-header-row {
  display: flex;
  justify-content: space-between;
  align-items: start;
  margin-bottom: 8px;
}

.color-pink { background: #fce4ec; }
.color-blue { background: #e3f2fd; }
.color-yellow { background: #fff9c4; }
.color-green { background: #e8f5e9; }
.color-purple { background: #f3e5f5; }
.color-orange { background: #ffe0b2; }

.project-rename-btn, .project-edit-desc-btn, .project-delete-btn {
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 4px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.project-rename-btn:hover, .project-edit-desc-btn:hover {
  background: var(--bg-2);
  color: var(--text);
}

.project-delete-btn:hover {
  background: rgba(234, 67, 53, 0.1);
  color: #ea4335;
}

.project-rename-btn:hover {
  background: #e3f2fd;
  color: #1976d2;
}

/* Streaming message bubble */
.msg.streaming {
  border-left: 3px solid #1976d2;
  animation: stream-pulse 1.5s ease-in-out infinite;
  white-space: pre-wrap;
}

@keyframes stream-pulse {
  0%, 100% { border-left-color: #1976d2; }
  50% { border-left-color: #64b5f6; }
}

/* Working indicator */
.working-indicator {
  font-size: 0.8rem;
  color: #1976d2;
  padding: 0.25rem 0;
  animation: working-blink 1.2s ease-in-out infinite;
}

@keyframes working-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* Send button danger state (stop) */
.composer button.danger-btn {
  background: #d32f2f;
  color: #fff;
}

.composer button.danger-btn:hover {
  background: #b71c1c;
}

/* Attach button */
.attach-btn { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--line); background: transparent; color: var(--text); font-size: 22px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: background 0.15s, border-color 0.15s; flex-shrink: 0; }
.attach-btn:hover { background: rgba(255,255,255,0.06); border-color: var(--brand); }

/* Send button disabled */
#sendBtn:disabled { opacity: 0.4; cursor: not-allowed; }
#sendBtn:disabled:hover { background: var(--brand); }

/* File staging area */
.file-staging { display: flex; flex-wrap: wrap; gap: 8px; padding: 8px 0; }
.file-staging.hidden { display: none; }
.file-staging-item { position: relative; width: 56px; height: 56px; border-radius: 8px; border: 1px solid var(--line); overflow: hidden; background: rgba(255,255,255,0.04); flex-shrink: 0; }
.file-staging-item img { width: 100%; height: 100%; object-fit: cover; }
.file-staging-item .file-icon { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 22px; color: var(--muted); }
.file-staging-item .remove-btn { position: absolute; top: -2px; right: -2px; width: 18px; height: 18px; border-radius: 50%; background: rgba(0,0,0,0.7); color: #fff; border: none; font-size: 11px; cursor: pointer; display: flex; align-items: center; justify-content: center; line-height: 1; padding: 0; }
.file-staging-item .remove-btn:hover { background: #d32f2f; }
.file-staging-item .file-name { position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.6); color: #fff; font-size: 9px; padding: 1px 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }


/* 响应式设计 */
@media (max-width: 1024px) {
  :root {
    --project-card-min-width: 300px;
    --projects-container-padding: 24px 32px;
  }
}

@media (max-width: 768px) {
  :root {
    --project-card-min-width: 100%;
    --projects-container-padding: 16px;
    --project-card-gap: 16px;
  }

  .projects-grid {
    grid-template-columns: 1fr;
  }

  .projects-header {
    flex-direction: column;
    gap: 16px;
    align-items: flex-start;
  }

  .projects-header-right {
    width: 100%;
    justify-content: space-between;
  }

  .workspace-layout {
    grid-template-columns: 200px minmax(0, 1fr) 250px;
  }
}

/* 旧「控制台」视图（.console-* / .summary-* / .hourly-chart / .chart-bar / .record-*）已随
   #consoleView 一起下线，178 行规则在 HTML/JS 里零引用，2026-08-03 删除。
   Token 用量总览现在在管理后台，用的是另一套 .adm-* 前缀。 */
.empty-state {
  text-align: center;
  color: var(--muted);
  padding: 40px;
  font-size: 14px;
}

/* 用户菜单下拉 */
.user-menu-wrapper {
  position: relative;
}

.user-avatar-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--brand-soft);
  color: var(--brand);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--brand);
  padding: 0;
  transition: all 0.2s ease;
}

.user-avatar-btn:hover {
  background: var(--brand);
  color: white;
  transform: scale(1.05);
}

.user-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow-hover);
  min-width: 200px;
  z-index: 1000;
  overflow: hidden;
}

.user-dropdown.hidden {
  display: none;
}

.user-dropdown-header {
  padding: 16px;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
}

.user-dropdown-item {
  width: 100%;
  padding: 12px 16px;
  background: none;
  border: none;
  text-align: left;
  font-size: 14px;
  color: var(--text);
  cursor: pointer;
  transition: background 0.2s ease;
}

.user-dropdown-item:hover {
  background: var(--bg-2);
  transform: none;
}

/* 个人中心样式 */
/* ===== 个人中心 v2（neumorphic） ===== */
.profile-center-v2 {
  position: fixed;
  inset: 0;
  background: var(--page-bg);
  z-index: 2000;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
.profile-center-v2.hidden { display: none; }

.pc-topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 20px 36px;
  border-bottom: 1px solid rgba(120,130,170, 0.12);
  background: rgba(255,255,255, 0.55);
  backdrop-filter: blur(8px);
  flex-shrink: 0;
}
.pc-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  color: #5d53ae;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 10px;
  border-radius: 8px;
}
.pc-back:hover { background: rgba(136,107,238, 0.08); }
.pc-back i { font-size: 17px; }
.pc-badge {
  width: 36px;
  height: 36px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  color: #fff;
}
.pc-badge i { font-size: 18px; }
.pc-badge-blue {
  background: linear-gradient(135deg, var(--neu-grad-blue-start), var(--neu-grad-blue-end));
  box-shadow: 2px 2px 4px rgba(90, 130, 216, 0.25);
}
.pc-title {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  color: var(--neu-text-primary);
  flex: 1;
}

/* ⚠ 版心是【放在 .pc-main 上，不是放在 body 上】——设计稿就是这么分层的（.dc.html:406/413）：
   顶栏满宽 → body 满宽 → 侧栏定宽贴左 → 主区填满 → 卡片自己限行宽。
   原来把 1400px 上限放在 body，导致满宽的 .pc-topbar 下面挂着一个居中的侧栏，
   左边界对不上，观感就是「内容从屏幕中间才开始」。 */
.pc-body {
  flex: 1;
  display: flex;
  max-width: var(--app-max-width);
  width: 100%;
  margin: 0 auto;
}

.pc-sidenav {
  width: 220px;
  padding: 28px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex-shrink: 0;
}
.pc-navitem {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 18px;
  border-radius: 12px;
  background: transparent;
  border: 0;
  border-left: 3px solid transparent;
  font-size: 15px;
  color: var(--neu-text-secondary);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
  text-align: left;
}
.pc-navitem i { font-size: 17px; color: var(--neu-text-secondary); }
.pc-navitem:hover:not(.active) { background: rgba(136,107,238, 0.05); }
.pc-navitem.active {
  background: var(--neu-bg-1);
  color: #4a70b8;
  font-weight: 600;
  border-left-color: #886bee;
  box-shadow: 3px 3px 7px var(--neu-shadow-raised-dark),
              -3px -3px 7px var(--neu-shadow-raised-light);
}
.pc-navitem.active i { color: #4a70b8; }

.pc-main {
  flex: 1;
  padding: 28px 44px 44px;
  min-width: 0;
  max-width: 1180px;   /* 左对齐限行宽（不加 auto margin），别让设置项拉成一条两米长的横线 */
}

.pc-card {
  background: var(--neu-bg-1);
  border-radius: 20px;
  padding: 32px;
  box-shadow: 7px 7px 16px var(--neu-shadow-raised-dark),
              -7px -7px 16px var(--neu-shadow-raised-light);
  margin-bottom: 22px;
}
.pc-card-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 22px;
  font-size: 19px;
  font-weight: 700;
  color: var(--neu-text-hero);
}
.pc-card-icon { font-size: 20px; color: #886bee; }

/* tab 级标题行（不在卡片里，直接坐在 .pc-main 上）：左标题 + 右操作。
   目前只有「积分明细」用 —— 它的内容是一叠 .cd-* 卡片，需要一个卡片外的刷新入口。 */
.pc-tab-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 22px;
}
.pc-tab-head .pc-card-title { margin: 0; }

.pc-inforow {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 0;
  border-bottom: 1px solid rgba(120,130,170, 0.12);
}
.pc-inforow:last-child { border-bottom: 0; }
.pc-info-label {
  width: 120px;
  font-size: 15px;
  color: var(--neu-text-muted);
  font-weight: 500;
  flex-shrink: 0;
}
.pc-info-value {
  flex: 1;
  font-size: 16px;
  color: var(--neu-text-primary);
  font-weight: 500;
  word-break: break-all;
}
.pc-info-note {
  font-size: 13px;
  color: var(--neu-text-muted);
}

/* ============ 个人中心 · 存储空间进度条 ============
   配额只挡上传（AI 生成的图由容器内子进程直接写盘、拦不住），但测量含 outputs ⇒ 生成撑满后
   下一次上传就会被挡。此前前端一处都没展示，用户第一次知道有配额就是被拒那一刻。
   ★ 三档配色收在这里的三个变量里，元素上只切 data-level —— 别把色值写进行内 style
     （行内 background 是换肤那几轮的头号漏网点，同一份字面量被抄过三遍）。 */
.pc-storage {
  --storage-ok: #3fa66a;
  --storage-warn: #d98c1f;
  --storage-danger: #d04840;
  /* ★ 轨道底色必须自己定，不能借 --glass-fill-inset —— 那个是 rgba(255,255,255,.28)，
     是给「玻璃内部的输入框」用的半透明白；铺在浅色玻璃卡上等于隐形，
     线上实测截图里整条轨道**一点都看不见**（只剩一行字）。浅色底要深色调轨道。 */
  --storage-track: rgba(15, 23, 42, 0.12);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.pc-storage-bar {
  height: 10px;
  border-radius: 999px;
  overflow: hidden;               /* 让 fill 的圆角被轨道裁掉，100% 时两端才齐平 */
  background: var(--storage-track);
  border: 1px solid var(--glass-border, transparent);
}
.pc-storage-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--storage-ok);
  transition: width 0.35s ease, background-color 0.25s ease;
}
.pc-storage-fill[data-level='warn'] { background: var(--storage-warn); }
.pc-storage-fill[data-level='danger'] { background: var(--storage-danger); }
.pc-storage-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  color: var(--neu-text);
  font-variant-numeric: tabular-nums;   /* 轮询刷新时数字不跳宽 */
}
@media (prefers-reduced-motion: reduce) {
  .pc-storage-fill { transition: none; }
}
/* ★ 这里**刻意没有** @media (prefers-color-scheme: dark) 的分支。
   本站是单主题（永远浅色）：`--neu-bg-1` 恒为 #f8fafd，卡片底恒为半透明白，
   不随系统深色模式变化。给 .pc-storage 单独写一套深色 token 不会让卡片变深，
   只会让「深色系统 + 浅色页面」的用户拿到浅色调轨道铺在浅色卡上 = 又变回隐形。
   （上一轮就是这么写的，线上实测才发现。真要做深色主题是整站的事，不是这一张卡的事。） */
.pc-mini-btn {
  background: var(--neu-bg-1);
  border: 0;
  border-radius: 10px;
  padding: 8px 18px;
  font-size: 14px;
  font-weight: 600;
  color: #5d53ae;
  cursor: pointer;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  transition: box-shadow 0.15s ease;
}
.pc-mini-btn:hover {
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}

.pc-action {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 20px;
  border-radius: 14px;
  border: 0;
  background: linear-gradient(145deg, #f8fafd, #eef2f9);
  box-shadow: inset 1px 1px 3px var(--neu-shadow-inset-dark),
              inset -1px -1px 3px var(--neu-shadow-inset-light);
  cursor: pointer;
  text-align: left;
  margin-bottom: 12px;
  transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.pc-action:last-child { margin-bottom: 0; }
.pc-action:hover {
  box-shadow: 5px 5px 12px var(--neu-shadow-raised-dark),
              -5px -5px 12px var(--neu-shadow-raised-light);
}
.pc-action.danger:hover {
  box-shadow: 5px 5px 12px rgba(208, 80, 96, 0.25),
              -5px -5px 12px var(--neu-shadow-raised-light);
}
.pc-action-icon {
  width: 40px;
  height: 40px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  color: #fff;
  flex-shrink: 0;
}
.pc-action-icon i { font-size: 19px; }
.pc-icon-amber {
  background: linear-gradient(135deg, #f0c860, #d8a830);
  box-shadow: 2px 2px 4px rgba(216, 168, 48, 0.25);
}
.pc-icon-orange {
  background: linear-gradient(135deg, #e8a060, #d08040);
  box-shadow: 2px 2px 4px rgba(208, 128, 64, 0.25);
}
.pc-icon-red {
  background: linear-gradient(135deg, #e87060, #d04840);
  box-shadow: 2px 2px 4px rgba(208, 72, 64, 0.25);
}
.pc-icon-blue {
  background: linear-gradient(135deg, var(--neu-grad-blue-start), var(--neu-grad-blue-end));
  box-shadow: 2px 2px 4px rgba(90, 130, 216, 0.25);
}
.pc-action-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}
.pc-action-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--neu-text-primary);
}
.pc-action-desc {
  font-size: 13px;
  color: var(--neu-text-muted);
}
.pc-action-arrow {
  font-size: 16px;
  color: var(--neu-text-muted);
  flex-shrink: 0;
}

.pc-setting-item {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.pc-setting-label {
  font-size: 15px;
  color: var(--neu-text-primary);
  font-weight: 500;
}
.pc-select-wrap {
  position: relative;
}
.pc-select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  padding: 13px 42px 13px 18px;
  border-radius: 12px;
  border: 0;
  background: var(--neu-bg-1);
  color: var(--neu-text-secondary);
  font-size: 15px;
  font-family: inherit;
  cursor: pointer;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
}
.pc-select:focus {
  outline: none;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light),
              0 0 0 2px rgba(93,83,174, 0.30);
}
.pc-select-arrow {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 16px;
  color: #5d646f;
  pointer-events: none;
}
.pc-setting-hint {
  margin: 0;
  font-size: 13px;
  color: var(--neu-text-muted);
}

/* 产品信息模板 / 企业子账号的输入控件。
   ⚠ 原来这几处靠 profile-view.js 里的行内 style 上色（background:#fff），行内优先级压过
     任何非 !important 规则，换肤后是卡片里唯一的纯白块。样式收到这里，别再写回行内。
   ⚠ 它们在 .pc-card（玻璃面）内部 ⇒ 玻璃内层，不加 blur。 */
.pc-pi-field {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border: 1px solid var(--glass-field-border);
  border-radius: 10px;
  font-size: 14px;
  font-family: inherit;
  background: var(--glass-fill-inset);
  color: var(--neu-text-primary);
}
textarea.pc-pi-field { resize: vertical; }
.pc-pi-field:focus {
  outline: none;
  border-color: var(--neu-accent);
  box-shadow: 0 0 0 3px var(--brand-soft);
}
.pc-pi-field:disabled { opacity: .55; cursor: not-allowed; }
.pc-tpl-card {
  border: 1px solid var(--glass-border);
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 12px;
  background: var(--glass-fill-hi);
}

@media (max-width: 960px) {
  .pc-topbar { padding: 16px 20px; }
  .pc-sidenav { width: 200px; padding: 22px 14px; }
  .pc-main { padding: 22px 24px 36px; }
  .pc-card { padding: 24px; }
}
@media (max-width: 768px) {
  .pc-topbar { padding: 14px 14px; gap: 10px; }
  .pc-title { font-size: 18px; }
  .pc-body { flex-direction: column; }
  .pc-sidenav {
    width: 100%;
    padding: 10px 14px;
    flex-direction: row;
    overflow-x: auto;
    border-bottom: 1px solid rgba(120,130,170, 0.12);
  }
  .pc-navitem {
    flex: 0 0 auto;
    border-left: 0;
    border-bottom: 3px solid transparent;
    padding: 10px 14px;
    font-size: 14px;
  }
  .pc-navitem.active {
    border-left: 0;
    border-bottom-color: #886bee;
  }
  .pc-main { padding: 18px 14px 36px; }
  .pc-card { padding: 20px; border-radius: 16px; }
  .pc-card-title { font-size: 17px; }
  .pc-inforow { flex-wrap: wrap; gap: 10px; padding: 14px 0; }
  .pc-info-label { width: 90px; font-size: 14px; }
  .pc-info-value { font-size: 15px; }
}

/* 兼容旧引用：admin/projects 等仍使用 warning-box 与 form 通用类 */
.warning-box {
  background: #fff3cd;
  border: 1px solid #ffc107;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 16px;
  color: #856404;
}
.warning-box p { margin: 0 0 8px 0; }
.warning-box p:last-child { margin-bottom: 0; }
.warning-box strong { color: #d32f2f; font-weight: 600; }
.form-input { width: 100%; margin-bottom: 12px; }
.form-actions { display: flex; gap: 12px; margin-top: 16px; }
.form-actions button { flex: 1; }

.batch-actions {
  display: flex;
  gap: 8px;
  padding: 8px 16px;
  border-bottom: 1px solid var(--line);
}

.batch-actions.hidden {
  display: none;
}

.danger-text {
  color: #d32f2f;
}

.danger-text:hover {
  color: #b71c1c;
}

.edit-name-form {
  margin-top: 12px;
  padding: 16px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.edit-name-form.hidden {
  display: none;
}

/* ============================================================
   管理后台 v2 · Neumorphic（与 profile-credits-v2 同款体系）
   ============================================================ */
.adm-body-bg { background: var(--page-bg); min-height: 100vh; }

.adm-panel {
  position: fixed;
  inset: 0;
  background: var(--page-bg);
  z-index: 2000;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  color: var(--neu-text-primary);
  font-family: 'Noto Sans SC', system-ui, -apple-system, BlinkMacSystemFont, "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", sans-serif;
}
.adm-panel.hidden { display: none; }

.adm-topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 28px;
  border-bottom: 1px solid var(--neu-line);
  background: var(--neu-bg-1);
  box-shadow: 0 2px 8px rgba(120,130,170,0.18);
  flex-shrink: 0;
}
.adm-back {
  background: var(--neu-bg-1);
  border: 0;
  color: var(--neu-text-secondary);
  font-size: 14px;
  font-weight: 600;
  padding: 9px 16px;
  border-radius: 10px;
  display: inline-flex; align-items: center; gap: 6px;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  transition: all .2s ease;
  cursor: pointer;
}
.adm-back:hover {
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  transform: none;
}
.adm-badge {
  width: 32px; height: 32px;
  border-radius: 10px;
  display: grid; place-items: center;
  color: #fff;
  font-size: 18px;
  box-shadow: 3px 3px 6px rgba(40,133,239,0.30),
              -2px -2px 4px var(--neu-shadow-raised-light);
}
.adm-badge-blue  { background: linear-gradient(145deg, var(--neu-grad-blue-start),  var(--neu-grad-blue-end)); }
.adm-badge-teal  { background: linear-gradient(145deg, var(--neu-grad-teal-start),  var(--neu-grad-teal-end)); }
.adm-badge-amber { background: linear-gradient(145deg, var(--neu-grad-amber-start), var(--neu-grad-amber-end)); }
.adm-badge-rose  { background: linear-gradient(145deg, var(--neu-grad-rose-start),  var(--neu-grad-rose-end)); }
.adm-title { margin: 0; font-size: 22px; font-weight: 800; color: var(--neu-text-hero); letter-spacing: .3px; }

.adm-body {
  display: flex;
  flex: 1;
  overflow: hidden;
  min-height: 0;
}

.adm-sidenav {
  width: 220px;
  padding: 22px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--neu-bg-1);
  border-right: 1px solid var(--neu-line);
  flex-shrink: 0;
}
.adm-navitem {
  background: transparent;
  border: 0;
  padding: 12px 16px;
  border-radius: 11px;
  text-align: left;
  color: var(--neu-text-secondary);
  font-size: 14px;
  font-weight: 600;
  display: inline-flex; align-items: center; gap: 10px;
  cursor: pointer;
  transition: all .18s ease;
}
.adm-navitem i { font-size: 17px; }
.adm-navitem:hover {
  color: var(--neu-text-primary);
  background: var(--neu-bg-1);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  transform: none;
}
.adm-navitem.active {
  color: var(--neu-accent);
  background: var(--neu-bg-1);
  border-left: 3px solid var(--neu-brand-start);
  padding-left: 11px;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
}

.adm-main {
  flex: 1;
  overflow-y: auto;
  padding: 28px 36px 48px;
  min-width: 0;
}
.adm-content { max-width: var(--app-max-width); margin: 0 auto; }

/* ============================== 通用卡片 ============================== */
.adm-card {
  background: var(--neu-bg-1);
  border-radius: 18px;
  padding: 22px 26px;
  box-shadow: 6px 6px 14px var(--neu-shadow-raised-dark),
              -6px -6px 14px var(--neu-shadow-raised-light);
  margin-bottom: 18px;
}
.adm-card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}
.adm-card-title {
  margin: 0 0 16px 0;
  font-size: 18px;
  font-weight: 700;
  color: var(--neu-text-hero);
  display: inline-flex; align-items: center; gap: 9px;
}
.adm-card-head .adm-card-title { margin: 0; }
.adm-card-icon { font-size: 20px; color: var(--neu-accent); }
.adm-card-sub { color: var(--neu-text-muted); font-size: 13px; font-weight: 500; }

/* ============ 可折叠卡片（<details class="adm-card adm-fold">，用户详情里那几张长卡）============
   刻意用【原生 details】而不是 admin 里 .adm-stack-card 那套「记 expandedId → 整块重渲染」：
   这几张卡里的输入（产品信息模板字段、专属 skill 的 allow/deny）保存前是纯 DOM 态，
   重渲染会把没保存的内容冲掉。details 只是隐藏，body 始终在树上，事件绑定与草稿都不受影响。
   外观完全继承 .adm-card（玻璃层按 class 命中，见文件末尾那两张名单），这里只处理折叠头本身。 */
.adm-fold > summary {
  /* 三条都要：Chrome 老版认 ::-webkit-details-marker，新版与 FF 认 ::marker，Safari 认 list-style */
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 10px;
  user-select: none;
}
.adm-fold > summary::-webkit-details-marker { display: none; }
.adm-fold > summary::marker { content: ''; }
/* ⚠ .adm-card-title 自带 margin:0 0 16px 0 —— 不清掉的话折叠状态下卡片底部凭空多 16px 空档。
   同 .adm-card-head .adm-card-title 那条，是同一个坑。展开时再由下面那条把间距补回来。 */
.adm-fold > summary > .adm-card-title { margin: 0; }
.adm-fold[open] > summary { margin-bottom: 16px; }
/* 折叠状态下也看得见「里面有多少东西」，省得为了确认空不空而挨个点开 */
.adm-fold-badge {
  flex: none;
  font-weight: 400;
  font-size: 12px;
  color: var(--neu-accent);
  background: var(--brand-soft);
  border-radius: 999px;
  padding: 2px 10px;
}
.adm-fold-chevron {
  margin-left: auto;
  flex: none;
  font-size: 18px;
  color: var(--neu-text-muted);
  transition: transform 0.18s ease;
}
.adm-fold[open] > summary .adm-fold-chevron { transform: rotate(180deg); }

/* ============================== 用户表格 ============================== */
.adm-table-wrap { overflow-x: auto; }
.adm-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
  color: var(--neu-text-primary);
}
.adm-table thead th {
  text-align: left;
  font-weight: 700;
  color: var(--neu-text-muted);
  font-size: 13px;
  letter-spacing: .6px;
  text-transform: uppercase;
  padding: 12px 14px;
  border-bottom: 1px solid var(--neu-line);
}
.adm-table tbody td {
  padding: 14px 14px;
  border-bottom: 1px solid var(--neu-line);
  vertical-align: middle;
}
.adm-table tbody tr:last-child td { border-bottom: 0; }
.adm-table tbody tr:hover { background: rgba(136,107,238,0.06); }
.adm-table-actions { text-align: right; }

/* 用户表里这两个可输入控件的宽度上下限（原来只有内联 max-width，没有下限）。
   ⚠ 表格是 auto 布局 + width:100%：容器一窄，auto 布局就按内容比例挤，实测 1024/768 两档
   都把它们压到 30px 的一条缝（下拉几乎点不开）。给下限后表格自然变宽，
   外层 .adm-table-wrap 的 overflow-x 接手横向滚动 —— 控件本身始终保持可用尺寸。
   ★ 单一真源在这里，别再往 admin-view.js 的标签上写内联 max-width。 */
.adm-userlist-card .row-scheme-select { min-width: 140px; max-width: 180px; }
.adm-userlist-card .row-note-input { min-width: 120px; max-width: 160px; }

.adm-cell-muted { color: var(--neu-text-muted); }
.adm-cell-strong { color: var(--neu-text-hero); font-weight: 700; }
.adm-user-name { font-weight: 600; color: var(--neu-text-primary); }
.adm-admin-badge {
  display: inline-block;
  padding: 2px 10px;
  font-size: 11px;
  font-weight: 700;
  border-radius: 7px;
  margin-left: 8px;
  background: linear-gradient(145deg, var(--neu-grad-blue-start), var(--neu-grad-blue-end));
  color: #fff;
  box-shadow: 1px 1px 3px rgba(40,133,239,0.30);
}
.adm-btn-view {
  background: var(--neu-bg-1);
  border: 0;
  color: var(--neu-accent);
  padding: 7px 14px;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 600;
  display: inline-flex; align-items: center; gap: 6px;
  box-shadow: 2px 2px 4px var(--neu-shadow-raised-dark),
              -2px -2px 4px var(--neu-shadow-raised-light);
  cursor: pointer;
  transition: all .15s ease;
}
.adm-btn-view:hover {
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  transform: none;
}
.adm-empty {
  text-align: center;
  color: var(--neu-text-muted);
  padding: 36px 0;
  font-size: 14px;
}

/* ============================== 用户详情 ============================== */
.adm-detail-head {
  display: flex; align-items: center; gap: 18px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.adm-back-pill {
  background: var(--neu-bg-1);
  border: 0;
  color: var(--neu-text-secondary);
  padding: 9px 16px;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  display: inline-flex; align-items: center; gap: 6px;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  cursor: pointer;
  transition: all .2s ease;
}
.adm-back-pill:hover {
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  transform: none;
}
.adm-detail-title { display: flex; align-items: center; gap: 12px; }
.adm-detail-avatar {
  width: 44px; height: 44px;
  border-radius: 12px;
  display: grid; place-items: center;
  color: #fff;
  font-size: 22px;
  background: linear-gradient(145deg, var(--neu-grad-blue-start), var(--neu-grad-blue-end));
  box-shadow: 3px 3px 6px rgba(40,133,239,0.30),
              -2px -2px 4px var(--neu-shadow-raised-light);
}
.adm-detail-meta h2 { margin: 0; font-size: 20px; font-weight: 800; color: var(--neu-text-hero); }
.adm-detail-handle { font-size: 13px; color: var(--neu-text-muted); }

/* 信息行 */
.adm-info-grid { display: flex; flex-direction: column; }
.adm-info-row {
  display: flex; align-items: center;
  padding: 14px 0;
  border-bottom: 1px solid var(--neu-line);
  font-size: 14px;
}
.adm-info-row:last-child { border-bottom: 0; }
.adm-info-label { color: var(--neu-text-muted); width: 160px; flex-shrink: 0; }
.adm-info-value { color: var(--neu-text-primary); }
.adm-mono { font-family: ui-monospace, SFMono-Regular, "SF Mono", monospace; font-size: 13px; }

/* 积分卡 */
.adm-credit-card { }
.adm-credit-hero {
  margin: 6px 0 18px;
  display: flex; align-items: baseline; gap: 8px;
}
.adm-credit-num {
  font-size: 42px;
  font-weight: 800;
  color: var(--neu-text-hero);
  letter-spacing: .5px;
}
.adm-credit-suffix { font-size: 15px; color: var(--neu-text-muted); }

.adm-credit-actions { display: flex; gap: 12px; flex-wrap: wrap; }

.adm-btn {
  border: 0;
  padding: 10px 18px;
  border-radius: 11px;
  font-size: 14px;
  font-weight: 600;
  display: inline-flex; align-items: center; gap: 7px;
  cursor: pointer;
  transition: all .15s ease;
}
.adm-btn-primary {
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  color: #fff;
  box-shadow: 3px 3px 6px rgba(40,133,239,0.30),
              -2px -2px 4px var(--neu-shadow-raised-light);
}
.adm-btn-primary:hover {
  box-shadow: 2px 2px 4px rgba(40,133,239,0.25),
              inset -1px -1px 3px rgba(255,255,255,0.20);
  transform: translateY(-1px);
}
.adm-btn-soft {
  background: var(--neu-bg-1);
  color: var(--neu-text-secondary);
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
}
.adm-btn-soft:hover {
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  transform: none;
}
.adm-btn-danger {
  background: linear-gradient(145deg, var(--neu-grad-rose-start), var(--neu-grad-rose-end));
  color: #fff;
  box-shadow: 3px 3px 6px rgba(208,80,112,0.30),
              -2px -2px 4px var(--neu-shadow-raised-light);
}
.adm-btn-danger:hover { transform: translateY(-1px); }

/* 权限开关 */
.adm-toggle-row {
  display: flex; align-items: center; gap: 14px;
  padding: 4px 0;
  cursor: pointer;
}
.adm-toggle {
  appearance: none;
  -webkit-appearance: none;
  width: 44px; height: 24px;
  border-radius: 13px;
  position: relative;
  cursor: pointer;
  background: var(--neu-bg-1);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  transition: background .2s ease;
  flex-shrink: 0;
}
.adm-toggle::after {
  content: '';
  position: absolute;
  top: 3px; left: 3px;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: linear-gradient(145deg, #ffffff, #d8e0ec);
  box-shadow: 1px 1px 3px var(--neu-shadow-raised-dark);
  transition: left .2s ease, background .2s ease;
}
.adm-toggle:checked {
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  box-shadow: inset 1px 1px 3px rgba(40,133,239,0.40);
}
.adm-toggle:checked::after { left: 23px; background: linear-gradient(145deg, #ffffff, #f8fafd); }
.adm-toggle-label { display: flex; flex-direction: column; gap: 3px; }
.adm-toggle-title { font-size: 15px; font-weight: 600; color: var(--neu-text-primary); }
.adm-toggle-desc { font-size: 13px; color: var(--neu-text-muted); }

/* 项目列表 */
.adm-project-list {
  list-style: none; padding: 0; margin: 0;
  display: flex; flex-direction: column;
}
.adm-project-item {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--neu-line);
  font-size: 14px;
}
.adm-project-item:last-child { border-bottom: 0; }
.adm-project-item i { color: var(--neu-accent); font-size: 16px; }
.adm-project-name { color: var(--neu-text-primary); flex: 1; font-weight: 500; }
.adm-project-date { color: var(--neu-text-muted); font-size: 13px; }

/* mini 统计 */
.adm-stat-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
}
.adm-stat-row-4 { grid-template-columns: repeat(4, 1fr); }
.adm-stat-row-5 { grid-template-columns: repeat(5, 1fr); }
.adm-mini-stat {
  background: var(--neu-bg-1);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex; flex-direction: column; gap: 5px;
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.adm-mini-label { font-size: 12px; color: var(--neu-text-muted); letter-spacing: .4px; }
.adm-mini-value { font-size: 18px; font-weight: 700; color: var(--neu-text-hero); }

/* 时间分布柱图 */
.adm-chart {
  display: flex;
  align-items: flex-end;
  height: 220px;
  gap: 5px;
  padding: 16px 4px 28px;
}
.adm-chart-bar {
  flex: 1;
  background: linear-gradient(to top, var(--neu-brand-end), var(--neu-brand-start));
  border-radius: 4px 4px 0 0;
  position: relative;
  min-height: 3px;
  cursor: pointer;
  box-shadow: 1px 1px 2px rgba(40,133,239,0.25);
  transition: opacity .2s ease;
}
.adm-chart-bar:hover { opacity: .8; }
.adm-chart-label {
  position: absolute;
  bottom: -22px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 11px;
  color: var(--neu-text-muted);
  white-space: nowrap;
}

/* 详细记录 */
.adm-records-scroll {
  max-height: 560px;
  overflow-y: auto;
  background: var(--neu-bg-1);
  border-radius: 12px;
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  padding: 10px 16px;
  scrollbar-width: thin;
  scrollbar-color: rgba(136,107,238,0.4) transparent;
}
.adm-records-scroll::-webkit-scrollbar { width: 8px; }
.adm-records-scroll::-webkit-scrollbar-thumb { background: rgba(136,107,238,0.4); border-radius: 4px; }
.adm-records-list { display: flex; flex-direction: column; }
.adm-record-row {
  display: grid;
  grid-template-columns: 120px 72px 100px 1fr 110px;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--neu-line);
  align-items: center;
  font-size: 13px;
}
.adm-record-row:last-child { border-bottom: 0; }
.adm-record-time { color: var(--neu-text-muted); font-family: ui-monospace, monospace; }
.adm-record-tag {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 7px;
  font-size: 11px;
  font-weight: 700;
  justify-self: start;
}
.adm-record-tag.text { background: linear-gradient(145deg, #d8e8f8, #c0d4f0); color: #2885ef; }
.adm-record-tag.image { background: linear-gradient(145deg, #f0e0f0, #e0c8e8); color: #9060b0; }
.adm-record-model { color: var(--neu-text-secondary); font-size: 12px; }
.adm-record-meta { color: var(--neu-text-muted); font-size: 12px; }
.adm-record-session {
  color: var(--neu-text-primary);
  font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.adm-record-amount {
  color: #d05060;
  font-weight: 700;
  font-size: 13px;
  text-align: right;
  font-family: ui-monospace, monospace;
}
.adm-records-loadmore {
  margin-top: 12px;
  display: flex;
  justify-content: center;
  padding: 6px 0;
}
.adm-records-loadmore-btn {
  background: var(--neu-bg-1);
  border: 0;
  color: var(--neu-accent);
  padding: 9px 22px;
  border-radius: 11px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  transition: all .15s ease;
}
.adm-records-loadmore-btn:hover {
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  transform: none;
}
.adm-records-loadmore-btn:disabled {
  opacity: .55;
  cursor: not-allowed;
}

/* 危险卡 action row */
.adm-action-grid { display: flex; flex-direction: column; gap: 10px; }
.adm-action {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 14px 16px;
  border: 0;
  border-radius: 12px;
  background: var(--neu-bg-1);
  cursor: pointer;
  text-align: left;
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  transition: all .15s ease;
}
.adm-action:hover {
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  transform: none;
}
.adm-action-icon {
  width: 32px; height: 32px;
  border-radius: 9px;
  display: grid; place-items: center;
  color: #fff;
  font-size: 16px;
  flex-shrink: 0;
  box-shadow: 2px 2px 4px rgba(120,130,170,0.30);
}
.adm-icon-amber { background: linear-gradient(145deg, var(--neu-grad-amber-start), var(--neu-grad-amber-end)); }
.adm-icon-orange { background: linear-gradient(145deg, #e8a060, #d08040); }
.adm-icon-red { background: linear-gradient(145deg, var(--neu-grad-rose-start), var(--neu-grad-rose-end)); }
.adm-action-text { flex: 1; display: flex; flex-direction: column; gap: 3px; }
.adm-action-title { font-size: 14px; font-weight: 700; color: var(--neu-text-primary); }
.adm-action-desc { font-size: 12px; color: var(--neu-text-muted); }
.adm-action-arrow { color: var(--neu-text-muted); font-size: 15px; }
.adm-action-danger:hover .adm-action-title { color: #c04060; }


/* ============================== 后台卡片通用小件 ==============================
   ⚠ 这两个类名带着 cases / videos 字样，是因为它们最早生在「案例管理」「演示视频」两节里。
   那两节 2026-08-05 整节删除，而这两个类**早就被全站复用**了（操作行 4 处、提示条 32 处），
   所以留下并搬到这个中性节名下 —— 下次做同类清理时别看名字连坐。 */
.adm-cases-actions { display: flex; gap: 10px; align-items: center; }

.adm-videos-hint {
  margin: 0 0 16px;
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 13px;
  color: var(--neu-text-secondary);
  background: var(--neu-bg-2);
  box-shadow: inset 1px 1px 3px var(--neu-shadow-inset-dark), inset -1px -1px 3px var(--neu-shadow-inset-light);
}

/* ============================== 个人资料 ============================== */
.adm-profile { max-width: 720px; }

/* ============================== 响应式 ============================== */
@media (max-width: 1080px) {
  .adm-stat-row, .adm-stat-row-4, .adm-stat-row-5 {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 720px) {
  .adm-body { flex-direction: column; }
  .adm-sidenav {
    width: 100%;
    flex-direction: row;
    overflow-x: auto;
    padding: 12px;
    border-right: 0;
    border-bottom: 1px solid var(--neu-line);
  }
  .adm-navitem { flex-shrink: 0; }
  .adm-navitem.active { border-left: 0; border-bottom: 3px solid var(--neu-brand-start); padding-left: 14px; }
  .adm-main { padding: 18px 16px 36px; }
  .adm-stat-row, .adm-stat-row-4, .adm-stat-row-5 { grid-template-columns: 1fr 1fr; }
  .adm-record-row { grid-template-columns: 80px 50px 1fr 80px; }
  .adm-record-meta, .adm-record-model { display: none; }
}

/* ============================== 管理员登录页 ============================== */
.adm-login-screen {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--page-bg);
  font-family: 'Noto Sans SC', system-ui, -apple-system, BlinkMacSystemFont, "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", sans-serif;
  color: var(--neu-text-primary);
}
.adm-login-card {
  width: min(420px, 100%);
  background: var(--neu-bg-1);
  border-radius: 24px;
  padding: 40px 36px 32px;
  box-shadow: 8px 8px 20px var(--neu-shadow-raised-dark),
              -8px -8px 20px var(--neu-shadow-raised-light);
}
.adm-login-brand {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 6px;
}
.adm-login-brand i {
  width: 44px; height: 44px;
  border-radius: 12px;
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  color: #fff;
  display: grid; place-items: center;
  font-size: 24px;
  box-shadow: 3px 3px 8px rgba(40,133,239,0.30),
              -2px -2px 6px var(--neu-shadow-raised-light);
}
.adm-login-brand span {
  font-size: 22px;
  font-weight: 800;
  color: var(--neu-text-hero);
  letter-spacing: .3px;
}
.adm-login-subtitle {
  color: var(--neu-text-secondary);
  font-size: 14px;
  margin: 6px 0 22px;
}
.adm-login-error {
  background: rgba(232, 112, 144, 0.10);
  border: 0;
  box-shadow: inset 2px 2px 4px rgba(208, 80, 112, 0.18);
  color: #c04060;
  border-radius: 12px;
  padding: 10px 14px;
  font-size: 13px;
  margin-bottom: 14px;
  display: none;
}
.adm-login-error.show { display: block; }
.adm-login-form { display: grid; gap: 12px; }
.adm-login-form input {
  background: var(--neu-bg-1);
  border: 0;
  border-radius: 14px;
  padding: 14px 18px;
  font-size: 14px;
  color: var(--neu-text-primary);
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  width: 100%;
}
.adm-login-form input::placeholder { color: var(--neu-text-muted); }
.adm-login-form input:focus {
  outline: none;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light),
              0 0 0 2px rgba(93,83,174,0.30);
}
.adm-login-btn {
  margin-top: 4px;
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  color: #fff;
  border: 0;
  padding: 12px;
  border-radius: 13px;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 3px 3px 8px rgba(40,133,239,0.30),
              -2px -2px 4px var(--neu-shadow-raised-light);
  transition: transform .15s ease, box-shadow .15s ease;
}
.adm-login-btn:hover {
  transform: translateY(-1px);
  box-shadow: 4px 4px 10px rgba(40,133,239,0.35);
}
.adm-login-btn:active { transform: translateY(0); }

/* 工具调用显示样式 */
.tool-calls-container {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 8px;
  padding: 8px 0;
}

.tool-call {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 13px;
  transition: all 0.2s;
}

/* ⚠ 这条的特异性 (0,2,0) 高于文件末尾终端块里的 .tool-call (0,1,0) ⇒ 它会赢。
   原来是暗色时代的 rgba(255,255,255,.06/.12)，在浅底上等于「鼠标一放上去，底和边框就没了」。 */
.tool-call:hover {
  background: var(--glass-fill-hi);
  border-color: var(--glass-border-hi);
}

.tool-call-header {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.tool-icon {
  font-size: 16px;
  flex-shrink: 0;
}

.tool-name {
  font-weight: 600;
  color: #b8c5ff;
  flex-shrink: 0;
}

.tool-input {
  color: #d0d8f0;
  font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
  font-size: 12px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tool-status {
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  flex-shrink: 0;
  margin-left: auto;
}

.tool-status.pending {
  background: rgba(255, 193, 7, 0.15);
  color: #ffd54f;
  animation: pulse 1.5s ease-in-out infinite;
}

.tool-status.success {
  background: rgba(76, 175, 80, 0.15);
  color: #81c784;
}

.tool-status.error {
  background: rgba(244, 67, 54, 0.15);
  color: #e57373;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

/* Agent 工具特殊样式 */
.tool-call.tool-agent {
  background: linear-gradient(135deg, rgba(159, 176, 255, 0.12) 0%, rgba(159, 176, 255, 0.06) 100%);
  border-color: rgba(159, 176, 255, 0.25);
  border-width: 2px;
}

.tool-call.tool-agent:hover {
  background: linear-gradient(135deg, rgba(159, 176, 255, 0.16) 0%, rgba(159, 176, 255, 0.08) 100%);
  border-color: rgba(159, 176, 255, 0.35);
  box-shadow: 0 2px 8px rgba(159, 176, 255, 0.15);
}

.tool-call.tool-agent .tool-icon {
  font-size: 18px;
  animation: agentPulse 2s ease-in-out infinite;
}

@keyframes agentPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

.tool-agent-detail {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid rgba(159, 176, 255, 0.2);
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: max-height 0.3s ease, opacity 0.3s ease;
  max-height: 500px;
  opacity: 1;
  overflow: hidden;
}

.tool-agent-detail.collapsed {
  max-height: 0;
  opacity: 0;
  padding-top: 0;
  margin-top: 0;
  border-top: none;
}

.agent-type {
  font-size: 12px;
  color: #b8c5ff;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 4px 8px;
  background: rgba(159, 176, 255, 0.15);
  border-radius: 4px;
  display: inline-block;
  align-self: flex-start;
}

.agent-desc,
.agent-prompt {
  font-size: 12px;
  color: #d0d8f0;
  line-height: 1.5;
}

.agent-desc strong,
.agent-prompt strong {
  color: #b8c5ff;
  font-weight: 600;
  margin-right: 4px;
}

.agent-nested-tools {
  margin-top: 8px;
  padding-left: 20px;
  border-left: 2px solid rgba(59, 130, 246, 0.3);
}

.agent-nested-tools .tool-call {
  margin-bottom: 6px;
  font-size: 0.9em;
}

.agent-nested-tools .tool-call:last-child {
  margin-bottom: 0;
}

/* 工作指示器样式优化 */
.working-indicator {
  margin-top: 8px;
  font-size: 12px;
  color: #9fb0ff;
  font-style: italic;
  animation: fadeInOut 2s ease-in-out infinite;
}

@keyframes fadeInOut {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 1; }
}

/* 视图模式切换器 */
.view-mode-switcher {
  display: flex;
  gap: 4px;
  margin-left: auto;
  margin-right: 8px;
}
.view-mode-btn {
  padding: 0;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
  color: var(--muted);
  transition: all 0.15s;
  line-height: 1;
}
.view-mode-btn:hover {
  background: var(--bg-2);
  color: var(--text);
}
.view-mode-btn.active {
  background: var(--brand-soft);
  border-color: var(--brand);
  color: var(--brand);
}

/* 网格模式下的文件项 */
.file-item.grid-item {
  flex-direction: column;
  padding: 0 !important;
  gap: 0 !important;
  margin: 0 !important;
  border-radius: 0 !important;
  justify-content: flex-start;
  align-items: center;
  text-align: center;
  height: fit-content;
  min-height: auto;
}
.file-item.grid-item .file-thumbnail {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  border-radius: 4px;
  margin: 0 !important;
  background: var(--bg-2);
}
.file-item.grid-item .file-icon {
  font-size: 48px;
  margin: 0 !important;
}
.file-item.grid-item.small-grid .file-icon {
  font-size: 48px;
}
.file-item.grid-item.medium-grid .file-icon {
  font-size: 64px;
}
.file-item.grid-item .file-name {
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 100%;
  font-weight: 400;
  line-height: 1;
  padding: 2px 4px;
  margin: 0 !important;
}

/* Toast 通知系统 */
.toast-container {
  position: fixed;
  bottom: 80px;
  left: 20px;
  z-index: 10000;
  pointer-events: none;
  width: 0;
  height: 0;
}

.toast {
  position: relative;
  background: var(--neu-bg-1);
  color: var(--neu-text-primary);
  padding: 13px 20px;
  border-radius: 14px;
  border-left: 3px solid var(--neu-accent);
  font-size: 14px;
  line-height: 1.5;
  box-shadow: 5px 5px 12px var(--neu-shadow-raised-dark), -5px -5px 12px var(--neu-shadow-raised-light);
  max-width: 400px;
  width: max-content;
  word-wrap: break-word;
  pointer-events: auto;
  animation: fadeInOut 3s ease-in-out;
  margin-bottom: 10px;
}

@keyframes fadeInOut {
  0% {
    opacity: 0;
    transform: translateY(10px);
  }
  10% {
    opacity: 1;
    transform: translateY(0);
  }
  90% {
    opacity: 1;
    transform: translateY(0);
  }
  100% {
    opacity: 0;
    transform: translateY(10px);
  }
}

#ws-disconnect-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 9999;
  align-items: center;
  justify-content: center;
  pointer-events: all;
}
#ws-disconnect-overlay.visible {
  display: flex;
}
.disconnect-message {
  background: var(--bg-2, #1a1a2e);
  color: var(--text, #fff);
  padding: 24px 32px;
  border-radius: 12px;
  text-align: center;
  font-size: 16px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.4);
}
.disconnect-icon {
  font-size: 32px;
  margin-bottom: 12px;
}

#account-switched-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 10001;
  align-items: center;
  justify-content: center;
  pointer-events: all;
}
#account-switched-overlay.visible {
  display: flex;
}
#account-switched-overlay .disconnect-message {
  max-width: min(440px, 90vw);
  display: flex;
  flex-direction: column;
  align-items: center;
}
#account-switched-overlay .disconnect-message > div:not(.disconnect-icon) {
  line-height: 1.6;
}
#account-switched-overlay .primary-btn {
  align-self: stretch;
}

/* ============================================================
 * Weave-UI Phase 2-5 - Neumorphic
 * Phase 2: 登录注册 / Phase 3: 项目卡 / Phase 4-5: 工作台
 * ============================================================ */

/* ===== Phase 2 - Auth Screen ===== */
.auth-screen {
  background: var(--page-bg);
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px;
}
.auth-card {
  background: var(--neu-bg-1);
  border: none !important;
  border-radius: 24px;
  box-shadow: 8px 8px 20px var(--neu-shadow-raised-dark),
              -8px -8px 20px var(--neu-shadow-raised-light);
  padding: 40px 36px;
  width: min(440px, 100%);
}
.auth-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 6px;
}
.auth-brand i {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 26px;
  box-shadow: 3px 3px 8px rgba(40,133,239,0.30),
              -2px -2px 6px var(--neu-shadow-raised-light);
}
.auth-brand span {
  font-size: 24px;
  font-weight: 800;
  color: var(--neu-text-hero);
  letter-spacing: 0.5px;
}
.auth-subtitle {
  color: var(--neu-text-secondary);
  font-size: 15px;
  margin: 4px 0 24px;
}
.auth-card .back-btn {
  background: var(--neu-bg-1);
  border: none;
  border-radius: 12px;
  color: var(--neu-text-secondary);
  font-size: 13px;
  padding: 8px 14px;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  margin-bottom: 22px;
  transition: all 0.2s ease;
}
.auth-card .back-btn:hover {
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.auth-card .auth-tabs {
  background: var(--neu-bg-1);
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  border-radius: 14px;
  padding: 4px;
  gap: 4px;
  margin-bottom: 18px;
}
.auth-card .auth-tab {
  background: transparent;
  border: none;
  box-shadow: none;
  color: var(--neu-text-muted);
  font-weight: 600;
  min-height: 42px;
  border-radius: 11px;
  transition: all 0.2s ease;
}
.auth-card .auth-tab:hover {
  color: var(--neu-text-secondary);
  border-color: transparent;
}
.auth-card .auth-tab.active {
  background: var(--neu-bg-1);
  color: var(--neu-accent);
  border: none;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
}
.auth-card .auth-form input {
  background: var(--neu-bg-1);
  border: none;
  border-radius: 14px;
  padding: 14px 18px;
  font-size: 15px;
  color: var(--neu-text-primary);
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
}
.auth-card .auth-form input::placeholder {
  color: var(--neu-text-muted);
}
.auth-card .auth-form input:focus {
  outline: none;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light),
              0 0 0 2px rgba(93,83,174,0.30);
}
.auth-card .auth-form .primary-btn {
  margin-top: 6px;
}
.auth-card .auth-error {
  background: rgba(232, 112, 144, 0.10);
  border: none;
  box-shadow: inset 2px 2px 4px rgba(208, 80, 112, 0.18);
  color: #c04060;
  border-radius: 12px;
  padding: 10px 14px;
}

/* ===== Phase 3 - Projects View ===== */
.projects-page {
  background: var(--page-bg);
}
.top-navbar {
  background: var(--neu-bg-1);
  border-bottom: none;
  box-shadow: 0 4px 14px rgba(120,130,170,0.22);
  padding: 14px 56px;
}
.top-navbar .brand-btn,
.workspace-navbar .brand-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 17px;
  font-weight: 800;
  color: var(--neu-text-hero);
  background: transparent;
}
.top-navbar .brand-btn:hover,
.workspace-navbar .brand-btn:hover {
  color: var(--neu-accent);
}
.top-navbar .brand-btn i,
.workspace-navbar .brand-btn i {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 22px;
  box-shadow: 3px 3px 8px rgba(40,133,239,0.30);
}

.page-title-bar {
  padding: 32px 56px 16px;
  background: transparent;
}
.page-title-bar h1 {
  font-size: 32px;
  color: var(--neu-text-hero);
  font-weight: 800;
}

.projects-container {
  padding: 24px 56px 56px;
  max-width: var(--app-max-width);
  margin: 0 auto;
}
.projects-grid {
  gap: 28px;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}

.project-card {
  background: var(--neu-bg-1) !important;
  border: none !important;
  border-radius: 20px;
  padding: var(--project-card-padding);
  box-shadow: 8px 8px 20px var(--neu-shadow-raised-dark),
              -8px -8px 20px var(--neu-shadow-raised-light);
  transition: all 0.25s ease;
}
.project-card:hover {
  transform: translateY(-3px);
  box-shadow: 12px 12px 28px var(--neu-shadow-raised-dark),
              -12px -12px 28px var(--neu-shadow-raised-light);
  border-color: transparent !important;
}

.project-card-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  font-size: 28px;
  display: grid;
  place-items: center;
  margin-bottom: 16px;
  color: #fff;
}
.project-card-icon.color-pink {
  background: linear-gradient(145deg, #f0a8c0, #d94b78);
  box-shadow: 4px 4px 10px rgba(208,80,112,0.30),
              -2px -2px 6px var(--neu-shadow-raised-light);
}
.project-card-icon.color-blue {
  background: linear-gradient(145deg, var(--neu-grad-blue-start), var(--neu-grad-blue-end));
  box-shadow: 4px 4px 10px rgba(40,133,239,0.35),
              -2px -2px 6px var(--neu-shadow-raised-light);
}
.project-card-icon.color-yellow {
  background: linear-gradient(145deg, var(--neu-grad-amber-start), var(--neu-grad-amber-end));
  box-shadow: 4px 4px 10px rgba(216,152,64,0.35),
              -2px -2px 6px var(--neu-shadow-raised-light);
}
.project-card-icon.color-green {
  background: linear-gradient(145deg, var(--neu-grad-teal-start), var(--neu-grad-teal-end));
  box-shadow: 4px 4px 10px rgba(58,168,152,0.35),
              -2px -2px 6px var(--neu-shadow-raised-light);
}
.project-card-icon.color-purple {
  background: linear-gradient(145deg, #b095e0, #7855c0);
  box-shadow: 4px 4px 10px rgba(120,85,192,0.30),
              -2px -2px 6px var(--neu-shadow-raised-light);
}
.project-card-icon.color-orange {
  background: linear-gradient(145deg, #f0b070, #d88040);
  box-shadow: 4px 4px 10px rgba(216,128,64,0.35),
              -2px -2px 6px var(--neu-shadow-raised-light);
}

.project-card-title {
  color: var(--neu-text-hero);
  font-size: 19px;
  font-weight: 700;
}
.project-card-description {
  color: var(--neu-text-secondary);
  font-size: 15px;
}
.project-card-meta {
  color: var(--neu-text-muted);
  font-size: 13px;
}

.project-card-actions {
  gap: 6px;
}
.project-rename-btn,
.project-edit-desc-btn,
.project-delete-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--neu-bg-1);
  color: var(--neu-text-secondary);
  box-shadow: 2px 2px 5px var(--neu-shadow-raised-dark),
              -2px -2px 5px var(--neu-shadow-raised-light);
  transition: all 0.2s ease;
}
.project-rename-btn:hover,
.project-edit-desc-btn:hover {
  background: var(--neu-bg-1);
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.project-delete-btn:hover {
  background: var(--neu-bg-1);
  color: #d94b78;
  box-shadow: inset 2px 2px 4px rgba(208,80,112,0.20),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}

.user-avatar-btn {
  background: var(--neu-bg-1) !important;
  border: none !important;
  color: var(--neu-text-secondary) !important;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
}
.user-avatar-btn:hover {
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end)) !important;
  color: #fff !important;
  box-shadow: 3px 3px 10px rgba(40,133,239,0.35),
              -2px -2px 6px var(--neu-shadow-raised-light);
}

.user-dropdown {
  background: var(--neu-bg-1) !important;
  border: none !important;
  border-radius: 16px;
  box-shadow: 8px 8px 20px var(--neu-shadow-raised-dark),
              -8px -8px 20px var(--neu-shadow-raised-light);
}
.user-dropdown-header {
  border-bottom: 1px solid var(--neu-line);
  color: var(--neu-text-hero);
  background: transparent;
}
.user-dropdown-item {
  color: var(--neu-text-secondary);
  background: transparent;
  transition: all 0.18s ease;
}
.user-dropdown-item:hover {
  background: var(--neu-bg-1);
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}

.token-usage-badge {
  background: var(--neu-bg-1) !important;
  border: none !important;
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  color: var(--neu-text-secondary) !important;
}

/* 空态：新拟物时代它是一块「凹进去的面」，所以给了实色底 + 内阴影。
   玻璃体系里「空」应该就是空的 —— 实色底压在 mesh 上会变成一个突兀的大白盒子。
   只留一圈极淡的虚线界定范围。 */
.empty-state {
  background: transparent;
  border: 1px dashed var(--glass-divider-line) !important;
  box-shadow: none;
  border-radius: 24px;
  color: var(--neu-text-muted);
}

/* ===== Phase 4 - Workspace expanded ===== */
.workspace-layout {
  background: var(--page-bg);
  transition: grid-template-columns 0.25s ease;
}

.workspace-navbar {
  background: var(--neu-bg-1);
  border-bottom: none;
  box-shadow: 0 4px 14px rgba(120,130,170,0.22);
}
.workspace-navbar .nav-link-btn {
  color: var(--neu-text-secondary);
  background: transparent;
}
.workspace-navbar .nav-link-btn:hover {
  color: var(--neu-accent);
}
.workspace-navbar .navbar-separator {
  color: var(--neu-text-muted);
}
.workspace-navbar .project-name-display {
  color: var(--neu-text-hero);
  font-weight: 600;
}

.left-panel,
.right-panel {
  background: transparent !important;
  border-right: none !important;
  border-left: none !important;
}
.center-panel {
  background: transparent;
}

.panel-header {
  background: transparent;
  border-bottom: none;
  /* 下内边距刻意比上小：与下面那一行（.session-input-container / .file-upload-container）
     的上内边距合起来才是标题与首个控件之间的间距，改一处要看另一处。 */
  padding: 16px 16px 8px;
}
.panel-header h2 {
  color: var(--neu-text-hero);
  font-size: 16px;
  font-weight: 700;
  margin: 0;
}

.toggle-btn {
  background: var(--neu-bg-1);
  border: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  color: var(--neu-text-secondary);
  display: grid;
  place-items: center;
  font-size: 12px;
  transition: all 0.18s ease;
}
.toggle-btn:hover {
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  color: var(--neu-accent);
}

.session-input-container {
  /* ⚠ 上内边距不能是 0：上面的「会话」标题行已经不是卡片了（没有边框来分隔），
     0 会让「新建对话」直接贴在标题下面。与 .panel-header 的 8px 下内边距合成 12px。 */
  padding: 4px 16px 14px;
}
.session-input-container input,
#sessionLabel,
#chatInput,
#currentPath {
  background: var(--neu-bg-1);
  border: none !important;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  color: var(--neu-text-primary);
  border-radius: 12px;
}
#sessionLabel:focus,
#chatInput:focus {
  outline: none;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light),
              0 0 0 2px rgba(93,83,174,0.25);
}

.session-list {
  padding: 8px 12px;
  gap: 8px;
}
.session-item {
  background: var(--neu-bg-1);
  border-radius: 14px;
  padding: 12px 14px;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  transition: all 0.18s ease;
}
.session-item:hover {
  box-shadow: 4px 4px 8px var(--neu-shadow-raised-dark),
              -4px -4px 8px var(--neu-shadow-raised-light);
}
.session-item.active {
  background: linear-gradient(145deg, rgba(136,107,238,0.18), rgba(40,133,239,0.28)) !important;
  color: var(--neu-accent) !important;
  box-shadow: inset 2px 2px 4px rgba(40,133,239,0.20),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.session-title {
  color: var(--neu-text-hero);
  font-weight: 700;
}
.session-sub {
  color: var(--neu-text-muted);
}
.session-item.active .session-title,
.session-item.active .session-sub {
  color: var(--neu-accent);
}

.session-more-btn {
  background: transparent;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  /* 与 .view-mode-btn 同理：24px 的盒子装 18px 的「⋯」，不显式居中就会偏 */
  display: grid;
  place-items: center;
  padding: 0;
  line-height: 1;
  color: var(--neu-text-muted);
  border: none;
}
.session-more-btn:hover {
  background: var(--neu-bg-1);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  color: var(--neu-text-secondary);
}

.chat-container {
  background: transparent;
}
.chat-header {
  background: transparent;
  border-bottom: none;
  padding: 12px 24px 4px;
  justify-content: flex-end;
}
.chat-header-actions .ghost-btn {
  background: var(--neu-bg-1);
  border: none;
  color: var(--neu-text-secondary);
  border-radius: 10px;
  padding: 6px 14px;
  font-size: 13px;
  box-shadow: 2px 2px 5px var(--neu-shadow-raised-dark),
              -2px -2px 5px var(--neu-shadow-raised-light);
  transition: all 0.18s ease;
}
.chat-header-actions .ghost-btn:hover {
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}

.chat-log {
  padding: 24px;
  gap: 18px;
  background: transparent;
}

.msg {
  border: none !important;
  font-size: 14.5px;
  padding: 14px 18px;
  border-radius: 18px;
  max-width: min(75%, 820px);
}
.msg.user {
  background: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end)) !important;
  color: #fff !important;
  border-bottom-right-radius: 6px !important;
  box-shadow: 4px 4px 10px rgba(40,133,239,0.30),
              -2px -2px 6px var(--neu-shadow-raised-light);
}
.msg.assistant {
  background: var(--neu-bg-1) !important;
  color: var(--neu-text-primary);
  border-bottom-left-radius: 6px !important;
  box-shadow: 4px 4px 10px var(--neu-shadow-raised-dark),
              -4px -4px 10px var(--neu-shadow-raised-light);
}
.msg.assistant::before {
  content: '小图';
  color: var(--neu-accent);
  font-weight: 800;
  letter-spacing: 0.4px;
}
.msg.thinking {
  border-style: solid !important;
  animation: weave-thinking-pulse 1.4s ease-in-out infinite;
}
@keyframes weave-thinking-pulse {
  0%, 100% { opacity: 0.78; }
  50%      { opacity: 1; }
}

.composer {
  background: var(--neu-bg-1);
  border-top: none !important;
  margin: 0 24px 24px;
  padding: 16px 18px;
  border-radius: 22px;
  box-shadow: 6px 6px 16px var(--neu-shadow-raised-dark),
              -6px -6px 16px var(--neu-shadow-raised-light);
}
.composer textarea {
  background: var(--neu-bg-1);
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  border-radius: 14px;
  padding: 10px 14px;   /* 与 .ff-textarea 同一件事：占位文字别离框顶太远 */
  border: none !important;
  color: var(--neu-text-primary);
}
.attach-btn {
  background: var(--neu-bg-1);
  border: none !important;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  color: var(--neu-text-secondary);
  font-size: 18px;
  transition: all 0.18s ease;
}
.attach-btn:hover {
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  color: var(--neu-accent);
}
.composer #sendBtn {
  padding: 12px 28px;
  border-radius: 14px;
}
.danger-btn {
  background: linear-gradient(145deg, #ea6878, #d94b78) !important;
  color: #fff !important;
  border: none !important;
  box-shadow: 4px 4px 10px rgba(208,80,112,0.30),
              -2px -2px 6px var(--neu-shadow-raised-light);
  border-radius: 14px;
}
.danger-btn:hover {
  box-shadow: 5px 5px 12px rgba(208,80,112,0.35),
              -3px -3px 8px var(--neu-shadow-raised-light);
}

.file-staging {
  background: transparent;
  padding: 8px 0;
}
.file-staging .staging-item,
.file-staging > div {
  background: var(--neu-bg-1);
  box-shadow: 2px 2px 4px var(--neu-shadow-raised-dark),
              -2px -2px 4px var(--neu-shadow-raised-light);
  border-radius: 10px;
  border: none !important;
}

/* Right panel (visual only) */
.right-panel .panel-header .view-mode-switcher {
  display: flex;
  gap: 4px;
}
.right-panel .view-mode-switcher button,
.view-mode-btn {
  background: var(--neu-bg-1);
  border: none !important;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  /* ⚠ 固定了宽高就必须显式居中：<button> 的匿名内容盒是靠字形自身对齐的，
     只给 width/height 不给 place-items，图标会偏。 */
  display: grid;
  place-items: center;
  padding: 0;
  line-height: 1;
  font-size: 16px;
  color: var(--neu-text-secondary);
  box-shadow: 2px 2px 4px var(--neu-shadow-raised-dark),
              -2px -2px 4px var(--neu-shadow-raised-light);
  transition: all 0.18s ease;
}
.view-mode-btn:hover {
  color: var(--neu-accent);
}
.view-mode-btn.active {
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  color: var(--neu-accent);
}
.file-upload-container {
  padding: 4px 16px 10px;
}
.file-upload-container .ghost-btn {
  background: var(--neu-bg-1);
  border: none;
  color: var(--neu-text-secondary);
  border-radius: 12px;
  padding: 8px 14px;
  width: 100%;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  transition: all 0.18s ease;
}
.file-upload-container .ghost-btn:hover {
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.current-path {
  background: var(--neu-bg-1);
  color: var(--neu-text-secondary);
  font-size: 12px;
  padding: 8px 14px;
  margin: 4px 16px;
  border-radius: 10px;
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.file-list {
  padding: 8px 12px;
  gap: 6px;
}
.file-item {
  background: transparent;
  border-radius: 10px;
  padding: 8px 12px;
  color: var(--neu-text-primary);
  transition: all 0.15s ease;
}
.file-item:hover {
  background: var(--neu-bg-1);
  box-shadow: 2px 2px 4px var(--neu-shadow-raised-dark),
              -2px -2px 4px var(--neu-shadow-raised-light);
}
.file-item.selected {
  background: var(--neu-bg-1) !important;
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.batch-actions {
  padding: 8px 16px;
  display: flex;
  gap: 8px;
}
.batch-actions .ghost-btn {
  background: var(--neu-bg-1);
  border: none;
  color: var(--neu-text-secondary);
  border-radius: 10px;
  padding: 6px 12px;
  font-size: 12px;
  box-shadow: 2px 2px 4px var(--neu-shadow-raised-dark),
              -2px -2px 4px var(--neu-shadow-raised-light);
}
.batch-actions .ghost-btn:hover {
  color: var(--neu-accent);
}
.batch-actions .danger-text {
  color: #d94b78;
}
.batch-actions .danger-text:hover {
  color: #d94b78;
  box-shadow: inset 2px 2px 4px rgba(208,80,112,0.20),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}

/* Resize handles —— 12px 的透明命中区；分栏线由面板自己的「玻璃棱」画（见文件末尾 ⑥c），
   这里【不再画任何线】。原来这一段是新拟物凹槽 + 一根 4×72px 的实心抓握杆
   （linear-gradient(145deg, --neu-bg-1, #cdd6e4)）—— 红线②把凸起的浅色半清零后它失去浮雕，
   只剩一根硬边灰蓝棍子；再叠上面板的棱和拖动条自画的两条 inset，一处挤了三四条平行竖线。
   现在抓握杆改成【静止不可见、hover/拖动才浮出】。 */
.resize-handle {
  width: 12px !important;
  background: transparent;
  transition: background 0.18s ease;
  z-index: 5;
}
.resize-handle::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 3px;
  height: 40px;
  border-radius: 999px;
  background: var(--glass-divider-line);
  opacity: 0;
  transition: opacity 0.15s ease, height 0.15s ease, background 0.15s ease;
}
.resize-handle:hover {
  background: var(--glass-fill-inset);
}
.resize-handle:hover::before {
  opacity: 1;
  height: 56px;
  background: var(--brand-grad);
}
.resize-handle.dragging {
  background: linear-gradient(180deg, rgba(136,107,238,0.12), rgba(40,133,239,0.22)) !important;
}
.resize-handle.dragging::before {
  opacity: 1;
  height: 72px;
  background: var(--brand-grad);
}

/* ===== Phase 5 - Workspace collapsed ===== */
.hamburger-btn {
  width: 40px;
  height: 40px;
  background: var(--neu-bg-1) !important;
  border: none !important;
  border-radius: 50% !important;
  color: var(--neu-text-secondary);
  box-shadow: 4px 4px 10px var(--neu-shadow-raised-dark),
              -4px -4px 10px var(--neu-shadow-raised-light);
  top: 76px;
  place-items: center;
  transition: all 0.2s ease;
}
.hamburger-btn.visible {
  display: grid;
}
.hamburger-btn:hover {
  color: var(--neu-accent);
  box-shadow: 5px 5px 12px var(--neu-shadow-raised-dark),
              -5px -5px 12px var(--neu-shadow-raised-light);
  transform: scale(1.06);
}
.hamburger-btn.left  { left: 16px; }
.hamburger-btn.right { right: 16px; }

/* ===== Tool calls — neumorphic theme adaptation =====
   原 2649-2826 段是深色主题颜色，Phase 2-5 后整体浅色化，需要重新着色。
   保留原 DOM 结构与 JS 行为（完成淡出、点击折叠）。 */

.tool-calls-container {
  margin-top: 4px;
  padding: 4px 0;
}

.tool-call {
  background: var(--neu-bg-1);
  border: none;
  border-radius: 12px;
  padding: 10px 14px;
  font-size: 13px;
  box-shadow: inset 2px 2px 5px var(--neu-shadow-inset-dark),
              inset -2px -2px 5px var(--neu-shadow-inset-light);
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}
/* ⚠ 全站有【两条】.tool-call:hover（另一条在 3357 一带），同特异性下这条靠后、它赢。
   两条都要维持正确：上面那条被删了也不会退回暗色残留，这条被删了也不会退回不透明底。
   hover 只做「填充变实一档」，不要 var(--neu-bg-1) 那种不透明底 —— 工具调用是坐在
   半透明助手气泡里的，一 hover 就跳成实色白块很扎眼。 */
.tool-call:hover {
  background: var(--glass-fill-hi);
  border-color: var(--glass-border-hi);
  box-shadow: var(--glass-shadow-sm);
}

.tool-call .tool-name { color: var(--neu-accent); font-weight: 700; }
.tool-call .tool-input { color: var(--neu-text-secondary); }
.tool-call .tool-icon { font-size: 16px; }

.tool-call .tool-status.pending {
  background: rgba(220, 150, 30, 0.16);
  color: #b87800;
}
.tool-call .tool-status.success {
  background: rgba(60, 150, 80, 0.16);
  color: #2f8050;
}
.tool-call .tool-status.error {
  background: rgba(200, 60, 90, 0.16);
  color: #a83050;
}

.tool-call.tool-agent {
  background: linear-gradient(145deg,
              rgba(136,107,238, 0.10),
              rgba(40,133,239, 0.06)),
              var(--neu-bg-1);
  border: none;
  box-shadow: 3px 3px 8px var(--neu-shadow-raised-dark),
              -3px -3px 8px var(--neu-shadow-raised-light);
}
.tool-call.tool-agent:hover {
  box-shadow: 4px 4px 10px rgba(40,133,239, 0.22),
              -3px -3px 8px var(--neu-shadow-raised-light);
}

.tool-agent-detail {
  border-top: 1px solid rgba(93,83,174, 0.25);
}
.agent-type {
  background: rgba(93,83,174, 0.14);
  color: var(--neu-accent);
}
.agent-desc,
.agent-prompt { color: var(--neu-text-secondary); }
.agent-desc strong,
.agent-prompt strong { color: var(--neu-accent); }
.agent-nested-tools {
  border-left: 2px solid rgba(93,83,174, 0.30);
}

/* 子代理（sidechain）内部步骤区：与「启动子智能体」气泡(.tool-call.tool-agent)同一视觉家族——
   外框=蓝色凸起 agent 卡，内部步骤=内陷工具卡(同 .tool-call)；完成步骤会淡出 */
.subagent-steps {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 8px 0 4px 0;
  padding: 10px 14px;
  border-radius: 12px;
  background: linear-gradient(145deg,
              rgba(136,107,238, 0.10),
              rgba(40,133,239, 0.06)),
              var(--neu-bg-1);
  box-shadow: 3px 3px 8px var(--neu-shadow-raised-dark),
              -3px -3px 8px var(--neu-shadow-raised-light);
}
.subagent-steps-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--neu-accent);
  letter-spacing: 0.02em;
  margin-bottom: 4px;
}
.subagent-step {
  font-size: 14px;
  padding: 8px 12px;
  border-radius: 10px;
  background: var(--neu-bg-1);
  box-shadow: inset 2px 2px 5px var(--neu-shadow-inset-dark),
              inset -2px -2px 5px var(--neu-shadow-inset-light);
}
.subagent-step .tool-call-header { gap: 8px; }
.subagent-step .tool-icon { font-size: 17px; }
.subagent-step .tool-name { color: var(--neu-accent); font-weight: 700; font-size: 14px; }
.subagent-step .tool-input { color: var(--neu-text-secondary); font-size: 13px; }
.subagent-step .tool-status { padding: 2px 8px; font-size: 11px; }
.subagent-step .tool-status.pending { background: rgba(220, 150, 30, 0.16); color: #b87800; }
.subagent-step .tool-status.success { background: rgba(60, 150, 80, 0.16); color: #2f8050; }
.subagent-step .tool-status.error { background: rgba(200, 60, 90, 0.16); color: #a83050; }

.working-indicator {
  color: var(--neu-accent);
  opacity: 0.85;
}

/* ===== Phase 4 mobile fix：抽屉态面板必须有不透明底色，否则会透出遮罩层 ===== */
@media (max-width: 960px) {
  .left-panel,
  .right-panel {
    background: var(--neu-bg-1) !important;
    box-shadow: 0 0 24px rgba(0, 0, 0, 0.18);
  }
  .left-panel .panel-header,
  .right-panel .panel-header {
    background: var(--neu-bg-1);
  }
}

/* ===== Phase 6 fix：项目卡片靠左排，单卡不再 1fr 拉满整行 ===== */
.projects-grid {
  grid-template-columns: repeat(auto-fill, minmax(var(--project-card-min-width), 420px)) !important;
  justify-content: start;
  margin: 0;
}
.projects-container {
  margin: 0 auto;
}

/* ===== Phase 6 fix：手机端整体收窄左右留白 ===== */
@media (max-width: 960px) {
  .page-title-bar { padding: 18px 14px 10px !important; }
  .top-navbar     { padding: 10px 14px !important; }
  .projects-container { padding: 8px 12px 16px !important; }
  .chat-log       { padding: 12px 10px !important; }
  .chat-header    { padding: 8px 10px 0 !important; justify-content: flex-end; }
  .composer       { padding: 10px 10px 12px !important; }
  .session-list   { padding: 6px 8px !important; }
  .file-list      { padding: 6px 8px !important; }
  .panel-header   { padding: 10px 12px !important; }
}
@media (max-width: 768px) {
  .page-title-bar h1 { font-size: 26px !important; }
}

/* ===== 手机端「我的项目」页：顶栏收窄留白 + 卡片紧凑 ===== */
@media (max-width: 600px) {
  /* 顶栏收窄留白；头像（→个人中心）永不被压缩挤出屏幕 */
  .top-navbar { gap: 8px; padding: 10px 12px !important; }
  .brand-btn { flex-shrink: 1; min-width: 0; }                  /* 空间不足时优先收缩品牌 */
  .user-info { gap: 8px; padding: 6px 10px; flex-shrink: 0; }   /* 首页那组「用户名+退出」收窄 */
  .top-navbar .user-menu-wrapper { flex-shrink: 0; }            /* 头像不被压缩 */
  /* 项目卡片更紧凑，单列不再空旷 */
  :root { --project-card-padding: 18px; --project-card-min-height: 0px; --project-card-gap: 12px; }
  .project-card-header-row { flex-wrap: wrap; gap: 8px; }       /* 标题+操作按钮窄屏不溢出 */
}

/* ===== 手机端工作区(聊天页)顶栏：收窄留白 + 精简左侧，头像(→个人中心)不被挤出屏幕 ===== */
@media (max-width: 960px) {
  .workspace-navbar { padding: 10px 14px !important; gap: 10px; }
  .workspace-navbar-left { min-width: 0; gap: 8px; overflow: hidden; }
  .workspace-navbar-left .brand-btn,
  .workspace-navbar-left .nav-link-btn,
  .workspace-navbar-left .navbar-separator { flex-shrink: 0; white-space: nowrap; }
  .workspace-navbar-left .project-name-display { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
  .workspace-navbar .user-menu-wrapper { flex-shrink: 0; }       /* 头像永不被压缩 */
}
@media (max-width: 600px) {
  /* 真·手机宽度：精简左侧装饰/次要信息，给头像和项目名让位 */
  .workspace-navbar-left .brand-btn span,        /* 隐藏「水马智能」文字，只留图标 */
  .workspace-navbar-left .navbar-separator { display: none; }    /* 隐藏 "/" 分隔符 */
}

/* ===== Phase 6：通用 prompt modal（输入 + 取消/确认 + 校验错误） ===== */
.modal-card.modal-prompt {
  width: 420px;
  max-width: calc(100% - 32px);
  text-align: left;
  padding: 28px 28px 24px;
}
.modal-card.modal-prompt .modal-icon { margin: 0 0 14px; }
.modal-card.modal-prompt .modal-title { text-align: left; }
.modal-card.modal-prompt .modal-text  { text-align: left; margin-bottom: 14px; }
.modal-label {
  display: block;
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--neu-text-secondary);
}
.modal-input {
  width: 100%;
  padding: 12px 14px;
  border-radius: 12px;
  border: none;
  background: var(--neu-bg-1);
  color: var(--neu-text-hero);
  font-size: 14px;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  box-sizing: border-box;
}
.modal-input:focus {
  outline: none;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light),
              0 0 0 2px rgba(93,83,174,0.30);
}
.modal-error {
  margin: 10px 0 0;
  min-height: 18px;
  font-size: 12px;
  color: #c04060;
  line-height: 1.5;
}
.modal-actions {
  display: flex;
  gap: 12px;
  justify-content: flex-end;
  margin-top: 20px;
}
.modal-actions .ghost-btn,
.modal-actions .primary-btn {
  flex: 0 0 auto;
  min-width: 92px;
  padding: 10px 18px;
  border-radius: 12px;
  font-size: 13px;
  font-weight: 600;
}
.modal-actions .ghost-btn {
  background: var(--neu-bg-1);
  color: var(--neu-text-secondary);
  border: none;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
}
.modal-actions .ghost-btn:hover {
  color: var(--neu-text-hero);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}

/* ============================== 栏目管理 ============================== */
/* ★ min-width 是必需的，不是保险丝：本表是 table-layout:fixed，前四列 + 末列都写死了 px
   （80+160+180+240+60 = 720，见 renderColumnsManagement 的 <th style="width:">）。
   容器只要窄于 720，唯一没声明宽度的「操作权限」列就被算成 **0**——实测 1024/768 两档下
   th 宽 0、单元格 28px、8 个复选框（内容宽 102px）从 display:flex 的 td 里溢出压到相邻列，
   行高从 82px 撑到 262px；而表格宽度恰好 == 容器宽，外层 overflow-x:auto 永远不触发。
   1100 = 720 固定列 + 380 权限列，380 是实测「8 个标签正好排 2 行」的宽度。
   ⚠ 以后加列或加宽列，这个数要跟着涨（columns-table-minwidth.test.js 会算这笔账）。 */
.adm-columns-card .adm-table { table-layout: fixed; width: 100%; min-width: 1100px; }
.adm-columns-table input.col-input {
  width: 100%;
  padding: 8px 10px;
  border: none;
  border-radius: 10px;
  background: var(--neu-bg-2);
  color: var(--neu-text-hero);
  font-family: inherit;
  font-size: 13px;
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.adm-columns-table input.col-input:focus { outline: 2px solid var(--neu-accent); }
.adm-col-perms { display: flex; flex-wrap: wrap; gap: 8px 14px; }
.adm-col-perm {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; color: var(--neu-text-hero);
  white-space: nowrap;
}
.adm-col-perm input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; }
.adm-col-order { display: flex; flex-direction: column; gap: 4px; align-items: center; }
.adm-icon-btn {
  width: 26px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; border-radius: 7px;
  background: var(--neu-bg-2); color: var(--neu-text-hero);
  cursor: pointer;
  box-shadow: 2px 2px 4px var(--neu-shadow-raised-dark),
              -2px -2px 4px var(--neu-shadow-raised-light);
}
.adm-icon-btn:hover { color: var(--neu-accent); }
.adm-icon-btn:active {
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.adm-col-actions { text-align: center; }

.composer-disclaimer {
  font-size: 12px;
  color: var(--muted);
  text-align: center;
  line-height: 1.5;
  padding: 2px 12px 0;
  user-select: none;
  letter-spacing: 0.02em;
}

/* ============ 工作计划：项目卡片 plan chip ============
   顶栏那个 .project-plan-badge 已删（2026-08-03）：它是纯展示、无点击，
   工作计划在项目卡片上已经标过一次了。 */
.project-card-plan-row {
  margin-top: 8px;
  margin-bottom: 4px;
}
.project-card-plan {
  display: inline-block;
  padding: 3px 10px;
  font-size: 12px;
  color: var(--muted);
  background: rgba(0, 0, 0, 0.04);
  border-radius: 999px;
  letter-spacing: 0.02em;
}

/* 「模型选项」下拉：2026-08-03 从工作区顶栏挪到了对话区顶栏（.chat-header-actions），
   跟「压缩」并排。所以外观跟着邻居 .chat-header-actions .ghost-btn 走，别再用
   rgba(0,0,0,.04) 那套换肤前的遗留底色 —— 压在磨砂玻璃上会是一块脏灰。
   它是 picker 不是输入框，不发 --glass-field-border（邻居也没有）。 */
.project-model-select {
  padding: 6px 28px 6px 12px;
  font-size: 13px;
  color: var(--neu-text-secondary);
  background-color: var(--neu-bg-1);
  border: none;
  border-radius: 10px;
  letter-spacing: 0.02em;
  cursor: pointer;
  max-width: 180px;
  appearance: none;
  -webkit-appearance: none;
  box-shadow: 2px 2px 5px var(--neu-shadow-raised-dark),
              -2px -2px 5px var(--neu-shadow-raised-light);
  transition: all 0.18s ease;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
}
.project-model-select:hover {
  color: var(--neu-accent);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.project-model-select:disabled { opacity: 0.6; cursor: default; }
@media (max-width: 600px) {
  .chat-header-actions .project-model-select { max-width: 120px; }
}

/* ============ 新建项目弹窗：工作计划按钮组 ============ */
.modal-newproject {
  max-width: 520px;
}
.plan-picker {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-top: 4px;
}
.plan-option {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 12px 14px;
  border: none;
  border-radius: 14px;
  background: var(--neu-bg-1);
  cursor: pointer;
  text-align: left;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
  font-family: inherit;
}
.plan-option:hover {
  transform: translateY(-1px);
}
.plan-option.is-selected {
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light),
              0 0 0 2px rgba(93,83,174, 0.45);
}
.plan-option-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--neu-text-hero);
}
.plan-option-id {
  font-size: 11px;
  color: var(--neu-text-muted);
  font-family: ui-monospace, SFMono-Regular, monospace;
}

/* ============ 产品信息可折叠区（新建 / 编辑项目弹窗共用；默认折叠，点开才填） ============
   ⚠ 这一片原来整块写死 #fff / #e5e7eb / #374151…，是全站换成磨砂玻璃时唯一漏掉的一块，
     在弹窗里显示为一个纯白盒子。配色一律走令牌，别再往回写十六进制。
   ⚠ 它坐在 .modal-card（已经是 --glass-fill-strong + blur）之上，属【玻璃内部】⇒ 不加 blur。 */
.pi-collapse {
  border: 1px solid var(--glass-border);
  border-radius: 10px;
  background: var(--glass-fill-hi);
  overflow: hidden;
}
.pi-collapse > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 13px;
  font-size: 14px;
  font-weight: 600;
  color: var(--neu-text-primary);
  user-select: none;
}
.pi-collapse > summary::-webkit-details-marker { display: none; }
.pi-collapse > summary::marker { content: ''; }
.pi-collapse-title { flex: 1; }
.pi-collapse-badge {
  font-weight: 400;
  font-size: 12px;
  color: var(--neu-accent);
  background: var(--brand-soft);
  border-radius: 999px;
  padding: 1px 8px;
}
.pi-collapse-chevron {
  transition: transform 0.18s ease;
  color: var(--neu-text-muted);
  font-size: 16px;
}
.pi-collapse[open] > summary .pi-collapse-chevron { transform: rotate(180deg); }
.pi-collapse-body {
  padding: 6px 13px 10px;
  border-top: 1px solid var(--glass-divider-line);
}
.pi-collapse-hint {
  margin: 8px 0 10px;
  font-size: 13px;
  color: var(--neu-text-muted);
  line-height: 1.5;
}
.pi-modal-row { margin-bottom: 10px; }
/* 输入控件：与全局 input/textarea 同形（玻璃内层，永不加 blur）。
   原来这几个字段靠 JS 里的行内 style 上色，行内优先级压过一切 ⇒ 已删，样式收在这里。 */
.pi-collapse .pi-modal-field,
.pi-collapse .pi-modal-tpl {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 11px;
  border: 1px solid var(--glass-field-border);
  border-radius: 9px;
  font-size: 14px;
  font-family: inherit;
  background: var(--glass-fill-inset);
  color: var(--neu-text-primary);
}
.pi-collapse textarea.pi-modal-field { resize: vertical; }
.pi-collapse .pi-modal-field:focus,
.pi-collapse .pi-modal-tpl:focus {
  outline: none;
  border-color: var(--neu-accent);
  box-shadow: 0 0 0 3px var(--brand-soft);
}

/* ============ 折叠卡片列表：管理员后台（工作计划 / 模型方案 / 模型选项共用） ============ */
.adm-stack-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 12px;
}
.adm-stack-card {
  border-radius: 12px;
  background: var(--neu-bg-1);
  box-shadow: 4px 4px 8px var(--neu-shadow-raised-dark),
              -4px -4px 8px var(--neu-shadow-raised-light);
  overflow: hidden;
  transition: box-shadow 0.18s ease;
}
.adm-stack-card.is-expanded {
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
}
.adm-stack-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  cursor: pointer;
  gap: 12px;
}
.adm-stack-titlerow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  min-width: 0;
}
.adm-stack-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--neu-text-hero);
}
.adm-stack-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  font-size: 11px;
  border-radius: 8px;
  background: rgba(120,130,170, 0.25);
  color: var(--neu-text-muted);
}
.adm-stack-badge-builtin {
  background: rgba(93,83,174, 0.14);
  color: var(--neu-accent);
}
.adm-stack-badge-muted {
  background: rgba(120,130,170, 0.25);
  color: var(--neu-text-muted);
}
.adm-stack-badge-warn {
  background: rgba(192, 57, 43, 0.12);
  color: #c0392b;
}
.adm-stack-count {
  font-size: 12px;
  color: var(--neu-text-muted);
  margin-left: 4px;
}
.adm-stack-chevron {
  color: var(--neu-text-muted);
  font-size: 18px;
  flex-shrink: 0;
}
.adm-stack-editor {
  padding: 12px 18px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  border-top: 1px solid var(--neu-line);
}
.adm-stack-field-label {
  font-size: 12px;
  color: var(--neu-text-muted);
  margin-top: 8px;
}
.adm-stack-hint {
  font-size: 11px;
  color: var(--neu-text-muted);
  margin: 4px 0 0;
  line-height: 1.5;
}
.adm-stack-hint code {
  font-family: ui-monospace, SFMono-Regular, monospace;
  background: rgba(120,130,170, 0.18);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 11px;
}
.adm-stack-name-input.adm-input[disabled] {
  opacity: 0.6;
  cursor: not-allowed;
}
.adm-stack-error {
  min-height: 18px;
  font-size: 12px;
  color: #d83b3b;
}
.adm-stack-editor-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}

/* ============ 计费配置：峰谷时段行 ============ */
.bill-bands { display: flex; flex-direction: column; gap: 12px; margin: 12px 0; }
.bill-band-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.02);
}
.bill-band-row .band-label { flex: 1 1 180px; min-width: 140px; }
.bill-band-fields { display: flex; gap: 10px; flex-wrap: wrap; }
.bill-band-fields label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--muted, #666);
}
.bill-band-fields .adm-input { width: 92px; }
.bill-band-fields .band-mult { width: 76px; }
.bill-band-days { display: flex; gap: 4px; flex-wrap: wrap; }
.bill-band-days .bill-day {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 12px;
  padding: 2px 4px;
}
.bill-band-row .btn-del-band { margin-left: auto; padding: 6px 10px; }
@media (prefers-color-scheme: dark) {
  .bill-band-row { border-color: rgba(255, 255, 255, 0.1); background: rgba(255, 255, 255, 0.03); }
}

/* ============ 企业用户管理：管理员置顶 + 子账号折叠 ============ */
.adm-ent-body {
  padding: 2px 16px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.adm-ent-subs {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 2px;
  padding-top: 8px;
  border-top: 1px dashed var(--neu-line);
}
.adm-ent-mrow {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--neu-bg-1);
  box-shadow: inset 1px 1px 3px var(--neu-shadow-inset-dark),
              inset -1px -1px 3px var(--neu-shadow-inset-light);
}

/* ============ 人群目录卡：双列紧凑网格 + per-user 勾选 ============ */
.adm-audience-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 6px 8px;
  margin: 10px 0 12px;
}
.adm-aud-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 6px 5px 10px;
  border-radius: 9px;
  min-width: 0;
  background: var(--neu-bg-1);
  box-shadow: inset 1px 1px 3px var(--neu-shadow-inset-dark),
              inset -1px -1px 3px var(--neu-shadow-inset-light);
  transition: background 0.15s ease;
}
/* 局部压掉全局 input{width:100%}，否则原生复选框会被撑满、把人群名推到最右缘 */
.adm-audience-list input[type="checkbox"] {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--neu-accent);
  cursor: pointer;
}
.adm-aud-row:has(input:checked) {
  background: rgba(93,83,174, 0.10);
}
.adm-aud-pick {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
  cursor: pointer;
  font-size: 13.5px;
  color: var(--neu-text-hero);
}
.adm-aud-pick span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.adm-aud-del {
  border: none;
  background: transparent;
  color: var(--neu-text-muted);
  cursor: pointer;
  padding: 3px 6px;
  border-radius: 6px;
  font-size: 14px;
  line-height: 1;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.adm-aud-row:hover .adm-aud-del,
.adm-aud-row:focus-within .adm-aud-del {
  opacity: 1;
}
.adm-aud-del:hover {
  color: #c0392b;
  background: rgba(192, 57, 43, 0.1);
}
.adm-aud-addrow {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 10px;
}
.adm-aud-addrow .aud-new-input {
  max-width: 240px;
}
/* ============ 积分账户卡（个人账户 / 企业共享池共用） ============ */
/* 三段：单次发放 / 发放计划 / 积分明细。段之间用细分隔线，不引入新色板。 */
.adm-credit-section {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid rgba(0, 0, 0, 0.07);
}
.adm-credit-subtitle {
  margin: 0 0 6px;
  font-size: 14px;
  font-weight: 700;
  color: var(--neu-text-primary);
  display: flex;
  align-items: center;
  gap: 6px;
}
.adm-credit-subtitle i { color: var(--neu-text-muted); }

/* 余额下面的状态行（预扣中 / 即将过期） */
.adm-credit-flag { margin: 4px 0 10px; font-size: 13px; }
.adm-credit-flag.is-reserved { color: #c0392b; }
.adm-credit-flag.is-expiring { color: #b8860b; }

/* 一行里的若干输入（发放 / 扣减）——窄屏自动换行 */
.adm-credit-row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: flex-start;
}
.adm-credit-row > label { flex: 1 1 180px; min-width: 160px; }
.adm-credit-row .adm-input { width: 100%; }

/* 账本里的规则行：可展开的发放计划条目 */
.adm-cp-item {
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.5);
  overflow: hidden;
}
.adm-cp-item.is-paused { opacity: .62; }
.adm-cp-new { margin-top: 10px; border-style: dashed; }
.adm-cp-summary {
  cursor: pointer;
  padding: 10px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  font-size: 13px;
  list-style: none;
}
.adm-cp-summary::-webkit-details-marker { display: none; }
.adm-cp-summary:hover { background: rgba(136,107,238, 0.06); }
.adm-cp-badge {
  flex-shrink: 0;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--neu-accent, #886bee);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center;
}
.adm-cp-amount { font-weight: 700; color: var(--neu-text-primary); }
.adm-cp-meta { color: var(--neu-text-muted); }
.adm-cp-body {
  padding: 4px 14px 14px;
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}
.adm-cp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 10px 14px;
  margin-top: 10px;
}
.adm-cp-grid .adm-input { width: 100%; }

/* ============ 积分账本：规则分组 + 每一笔批次 ============
   批次行用 flex 定宽列（不是 table）——规则行是 <details>，嵌在 <table> 里结构别扭；
   定宽列保证跨分组仍然对齐。批次多/窄屏时账本内部横滚，页面本身不横滚。 */
.adm-ledger {
  margin-top: 10px;
  overflow-x: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.adm-ledger-group {
  min-width: 640px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.5);
  overflow: hidden;
}
/* 规则行在分组里已经是容器的一部分，去掉它自己的框，避免双层边框 */
.adm-ledger-group > .adm-cp-item { border: 0; border-radius: 0; background: rgba(136,107,238, 0.07); }
.adm-ledger-lots { padding: 2px 0; }
.adm-ledger-empty {
  margin: 0;
  padding: 10px 14px;
  font-size: 13px;
  color: var(--neu-text-muted);
}
.adm-lot-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  font-size: 13px;
  border-top: 1px solid rgba(0, 0, 0, 0.05);
}
.adm-ledger-group > .adm-lot-row:first-child,
.adm-ledger-lots > .adm-lot-row:first-child { border-top: 0; }
.adm-lot-amount { flex: 0 0 90px; text-align: right; font-weight: 700; color: var(--neu-text-hero); }
.adm-lot-source { flex: 1 1 140px; min-width: 100px; color: var(--neu-text-primary); }
.adm-lot-time { flex: 0 0 150px; color: var(--neu-text-muted); }
.adm-lot-expiry { flex: 0 0 150px; color: var(--neu-text-muted); }
.adm-lot-actions { flex: 0 0 auto; margin-left: auto; display: flex; align-items: center; gap: 6px; }
.adm-lot-delta { width: 84px; padding: 5px 8px; font-size: 12px; }
.adm-ledger-total {
  margin-top: 10px;
  text-align: right;
  font-size: 13px;
  color: var(--neu-text-muted);
}
.adm-ledger-total strong { font-size: 15px; color: var(--neu-text-hero); }
.adm-btn-mini { padding: 5px 10px; font-size: 12px; border-radius: 8px; }

/* ============ 邀请码生成表单 ============ */
.adm-invite-newform {
  margin: 4px 0 16px;
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--neu-bg-1);
  box-shadow: inset 2px 2px 5px var(--neu-shadow-inset-dark),
              inset -2px -2px 5px var(--neu-shadow-inset-light);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.adm-invite-newrow {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.adm-invite-newrow .adm-stack-field-label {
  flex: 1 1 180px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 0;
}
.adm-invite-coderow {
  display: flex;
  gap: 8px;
  align-items: center;
}
.adm-invite-coderow .adm-input {
  flex: 1 1 auto;
}
.adm-invite-coderow .adm-btn {
  flex-shrink: 0;
}

/* ============ 管理员通用输入框（与 .modal-input 同源；后台编辑器 / 权限文本框 / 列输入框统一） ============ */
.adm-input {
  width: 100%;
  padding: 12px 14px;
  border-radius: 12px;
  border: none;
  background: var(--neu-bg-1);
  color: var(--neu-text-hero);
  font-size: 14px;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  box-sizing: border-box;
}
.adm-input:focus {
  outline: none;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light),
              0 0 0 2px rgba(93,83,174,0.30);
}

/* ============================================================
   fission-form layoutStyle
   ============================================================ */

.workspace-layout.workspace-style-fission-form,
.workspace-layout.workspace-style-product-card-form { grid-template-columns: 360px minmax(0, 1fr) 300px; }
.workspace-layout.workspace-style-fission-form.left-collapsed,
.workspace-layout.workspace-style-product-card-form.left-collapsed { grid-template-columns: 0 minmax(0, 1fr) 300px; }
.workspace-layout.workspace-style-fission-form.right-collapsed,
.workspace-layout.workspace-style-product-card-form.right-collapsed { grid-template-columns: 360px minmax(0, 1fr) 0; }
.workspace-layout.workspace-style-fission-form.both-collapsed,
.workspace-layout.workspace-style-product-card-form.both-collapsed { grid-template-columns: 0 minmax(0, 1fr) 0; }

/* fission / product-card-form 模式下隐藏 sessions sidebar，显示对应表单 */
.workspace-style-fission-form #leftPanel .session-only,
.workspace-style-product-card-form #leftPanel .session-only { display: none !important; }
.workspace-style-fission-form #fissionFormPanel,
.workspace-style-product-card-form #productCardSetFormPanel { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow-y: auto; padding: 12px 16px 16px; gap: 14px; }

/* 左栏折叠按钮条（panel-header-bar）：fission / freeform 通用 */
.left-panel .panel-header-bar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  /* ⚠ 不要写死 height：里面是个 28px 的圆按钮，8px 上内边距 + 28px = 36px 装不进 32px 的盒子，
     按钮会溢出到盒子外面。按内容定高即可。 */
  padding: 10px 12px 4px;
  background: transparent;
  border: none;
}
.left-panel .panel-header-bar .toggle-btn {
  background: var(--neu-bg-1);
  color: var(--neu-text-secondary);
  border: none;
  width: 28px; height: 28px;
  border-radius: 50%;
  font-size: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  cursor: pointer;
  transition: box-shadow 0.15s, transform 0.15s;
}
.left-panel .panel-header-bar .toggle-btn:hover {
  box-shadow: 2px 2px 4px var(--neu-shadow-raised-dark),
              -2px -2px 4px var(--neu-shadow-raised-light);
}
.left-panel .panel-header-bar .toggle-btn:active {
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
  transform: translateY(0);
}

/* ─────────── fission 拟态左栏 ─────────── */
.fission-form-panel {
  background: transparent;
  color: var(--neu-text-primary);
}
.fission-form-panel .ff-section { display: flex; flex-direction: column; gap: 10px; margin-bottom: 22px; }
.fission-form-panel .ff-section-title {
  font-size: 15px; font-weight: 600;
  color: var(--neu-text-primary);
  display: flex; align-items: center;
}
.fission-form-panel .ff-tip {
  color: var(--neu-text-muted);
  font-size: 12px;
  margin-left: 5px;
  cursor: help;
}

/* 上传卡：拟态凹陷 */
.fission-form-panel .ff-uploader {
  background: var(--neu-bg-1);
  border: none;
  border-radius: 14px;
  padding: 26px 16px;
  cursor: pointer;
  text-align: center;
  user-select: none;
  box-shadow: inset 4px 4px 8px var(--neu-shadow-inset-dark),
              inset -4px -4px 8px var(--neu-shadow-inset-light);
  transition: box-shadow 0.18s, background 0.18s;
}
.fission-form-panel .ff-uploader:hover {
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
}
.fission-form-panel .ff-uploader.dragging {
  background: linear-gradient(135deg, rgba(136,107,238,0.12), rgba(40,133,239,0.08));
  box-shadow: 4px 4px 10px var(--neu-shadow-raised-dark),
              -4px -4px 10px var(--neu-shadow-raised-light);
}
.fission-form-panel .ff-uploader.locked {
  cursor: not-allowed;
  opacity: 0.55;
}
.fission-form-panel .ff-uploader-cta {
  font-size: 15px; font-weight: 600;
  color: var(--neu-text-primary);
  margin-bottom: 6px;
}
.fission-form-panel .ff-uploader-arrow {
  display: inline-block;
  margin-right: 6px;
  font-size: 15px;
  color: var(--neu-accent);
}
.fission-form-panel .ff-uploader-sub {
  font-size: 13px;
  color: var(--neu-text-muted);
}

/* 已上传缩略图行：拟态凸起小卡 */
.fission-form-panel .ff-thumbs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.fission-form-panel .ff-thumb {
  position: relative;
  width: 72px; height: 72px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--neu-bg-1);
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
}
.fission-form-panel .ff-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fission-form-panel .ff-thumb-pdf {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
  color: var(--neu-text-secondary);
  background: var(--neu-bg-2);
}
.fission-form-panel .ff-thumb-remove {
  position: absolute; top: 3px; right: 3px;
  width: 20px; height: 20px; border-radius: 50%;
  background: rgba(58, 74, 107, 0.7);
  color: #fff;
  font-size: 13px; line-height: 1;
  border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
}

/* textarea / count：拟态凹陷 */
.fission-form-panel .ff-textarea {
  width: 100%; min-height: 76px;
  /* ⚠ 上内边距别再放大：占位文字距框顶 = padding-top + 行高的半铅空 + 字形上沿。
     12px + 1.55 行高时实测约 19px，比站内其它输入框（9~11px）明显靠下，
     看着就是「提示文字和框顶之间有一截莫名其妙的空白」。 */
  padding: 9px 12px;
  border: none; border-radius: 12px;
  font-size: 14px; font-family: inherit; line-height: 1.5;
  resize: vertical;
  color: var(--neu-text-primary);
  background: var(--neu-bg-1);
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  box-sizing: border-box;
  transition: box-shadow 0.15s;
}
.fission-form-panel .ff-textarea::placeholder { color: var(--neu-text-muted); }
.fission-form-panel .ff-textarea:focus {
  outline: none;
  box-shadow: inset 4px 4px 8px var(--neu-shadow-inset-dark),
              inset -4px -4px 8px var(--neu-shadow-inset-light);
}
.fission-form-panel .ff-textarea.ff-req { min-height: 130px; }

.fission-form-panel .ff-count-row { flex-direction: row; align-items: center; gap: 10px; margin-bottom: 22px; }
.fission-form-panel .ff-count-row .ff-section-title { margin-right: 8px; margin-bottom: 0; }
.fission-form-panel .ff-count {
  width: 90px; padding: 10px 12px;
  border: none; border-radius: 12px;
  font-size: 14px;
  color: var(--neu-text-primary);
  background: var(--neu-bg-1);
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  box-sizing: border-box;
}
.fission-form-panel .ff-count:focus {
  outline: none;
  box-shadow: inset 4px 4px 8px var(--neu-shadow-inset-dark),
              inset -4px -4px 8px var(--neu-shadow-inset-light);
}
.fission-form-panel .ff-count-unit { font-size: 14px; color: var(--neu-text-secondary); }

/* 目标人群下拉框：横排，标题在左，select 占满剩余宽度，拟态内阴影同 ff-count */
.fission-form-panel .ff-select-row { flex-direction: row; align-items: center; gap: 10px; margin-bottom: 22px; }
.fission-form-panel .ff-select-row .ff-section-title { margin-right: 8px; margin-bottom: 0; white-space: nowrap; }
.fission-form-panel .ff-select {
  flex: 1; min-width: 120px;
  padding: 10px 12px;
  border: none; border-radius: 12px;
  font-size: 14px;
  color: var(--neu-text-primary);
  background: var(--neu-bg-1);
  cursor: pointer;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  box-sizing: border-box;
}
.fission-form-panel .ff-select:focus {
  outline: none;
  box-shadow: inset 4px 4px 8px var(--neu-shadow-inset-dark),
              inset -4px -4px 8px var(--neu-shadow-inset-light);
}
.fission-form-panel .ff-select:disabled { opacity: 0.6; cursor: not-allowed; }

/* 创意图裂变倾向滑块：横排，滑块占满剩余宽度，右侧 0-5 读数 chip */
.fission-form-panel .ff-tendency-row { flex-direction: row; align-items: center; gap: 12px; margin-bottom: 22px; }
.fission-form-panel .ff-tendency-row .ff-section-title { margin-right: 8px; margin-bottom: 0; white-space: nowrap; }
/* ⚠ 这两个滑块曾经是【全站唯一没被换肤覆盖的原生控件】：只给了 accent-color，其余交给 UA 样式。
   Chrome 的 UA 表给 input[type=range] 加了 margin:2px，再加上原生轨道的圆角端点，
   value=0 时滑块看着并没有贴到最左边（用户报过）。
   appearance:none 之后滑块的行程被定义为 [track.left, track.right − thumb.width]，
   ⇒ min 时 thumb.left === track.left，这才是「0 就在最左边」。margin:0 干掉 UA 的 2px。 */
.fission-form-panel .ff-tendency-slider {
  -webkit-appearance: none;
  appearance: none;
  flex: 1; min-width: 0;
  height: 18px;
  margin: 0;
  padding: 0;
  /* ⚠ border 必须显式清掉：全局那条 `input:where(…)`（本文件顶部）给所有 input
     发了 `border: 1px solid var(--glass-field-border)` + `border-radius: 16px`。
     range 在它的命中范围内（当时只排除了 checkbox/radio），于是滑块外面多画了一个
     18px 高的圆角方框 —— 轨道才 6px，看着就是「滑块被框起来了」。
     同一面板里的 .ff-count 早就写了 border:none 中和它，这里漏了。
     不去全局那条里把 range 一起排除：那会连带丢掉 width:100%，滑块行程算法依赖它。 */
  border: none;
  background: transparent;
  cursor: pointer;
}
.fission-form-panel .ff-tendency-slider::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 999px;
  /* 填充宽度对齐【滑块中心】而不是它的左边缘，两端才不会突出去。
     --ff-p 是 0~1 的进度，由 view 里的 setFill() 写入 —— appearance:none 之后
     accent-color 那套自动填充就没有了，必须自己算。 */
  background:
    linear-gradient(90deg, var(--neu-brand-start), var(--neu-brand-end))
      left center / calc(var(--ff-p, 0) * (100% - 16px) + 8px) 100% no-repeat,
    var(--glass-fill-inset);
  box-shadow: inset 0 0 0 1px var(--glass-field-border);
}
.fission-form-panel .ff-tendency-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px; height: 16px;
  margin-top: -5px;                /* (轨道 6 − 滑块 16) / 2，把圆点压回轨道中线 */
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--glass-field-border);
  box-shadow: 0 2px 6px rgba(30,40,80,0.28);
}
.fission-form-panel .ff-tendency-slider:focus-visible {
  outline: none;
}
.fission-form-panel .ff-tendency-slider:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 2px 6px rgba(30,40,80,0.28), 0 0 0 3px rgba(93,83,174,0.30);
}
/* Firefox：轨道 / 已走过的进度 / 滑块是三个独立伪元素，进度由 UA 自己算，用不到 --ff-p */
.fission-form-panel .ff-tendency-slider::-moz-range-track {
  height: 6px; border-radius: 999px;
  background: var(--glass-fill-inset);
  box-shadow: inset 0 0 0 1px var(--glass-field-border);
}
.fission-form-panel .ff-tendency-slider::-moz-range-progress {
  height: 6px; border-radius: 999px;
  background: linear-gradient(90deg, var(--neu-brand-start), var(--neu-brand-end));
}
.fission-form-panel .ff-tendency-slider::-moz-range-thumb {
  width: 14px; height: 14px;
  border-radius: 50%;
  background: #fff;
  border: 1px solid var(--glass-field-border);
  box-shadow: 0 2px 6px rgba(30,40,80,0.28);
}
.fission-form-panel .ff-tendency-value {
  flex: none;
  min-width: 28px;
  text-align: center;
  font-size: 14px; font-weight: 600;
  color: var(--neu-accent);
  padding: 4px 10px; border-radius: 10px;
  background: var(--neu-bg-1);
  box-shadow: inset 2px 2px 4px var(--neu-shadow-inset-dark),
              inset -2px -2px 4px var(--neu-shadow-inset-light);
}
.fission-form-panel.locked .ff-tendency-slider { cursor: not-allowed; opacity: 0.6; }

/* 合规性强弱：与创意倾向同款横排滑块（复用 .ff-tendency-slider/.ff-tendency-value），
   说明文案挂在标题右侧的 ⓘ（.ff-tip）上，与本表单其余字段一致 */
.fission-form-panel .ff-compliance-section { margin-bottom: 22px; }
.fission-form-panel .ff-compliance-row { display: flex; flex-direction: row; align-items: center; gap: 12px; }
.fission-form-panel .ff-compliance-row .ff-section-title { margin-right: 8px; margin-bottom: 0; white-space: nowrap; }
.fission-form-panel .ff-compliance-value { min-width: 40px; }   /* 容纳「正常」两字 */

/* footer：sticky 底部，拟态主按钮 */
.fission-form-panel .ff-footer {
  position: sticky; bottom: -16px;
  background: var(--neu-bg-1);
  margin: 0 -16px -16px;
  padding: 14px 16px 16px;
  display: flex; flex-direction: column; gap: 10px;
  z-index: 2;
}
/* 顶部 16px 渐隐：实心 footer 与上方滚动内容之间平滑过渡 */
.fission-form-panel .ff-footer::before {
  content: ''; position: absolute; left: 0; right: 0; top: -16px; height: 16px;
  background: linear-gradient(to top, var(--neu-bg-1), transparent);
  pointer-events: none;
}
/* 「开始生图」是这一屏的主动作，设计稿 .dc.html:538 是品牌渐变药丸。
   原来用的是 --neu-grad-blue-*（功能卡那套四色里的蓝），换肤后和全站主按钮不是一个颜色。 */
.fission-form-panel .ff-primary {
  width: 100%;
  padding: 14px 18px;
  background: var(--brand-grad);
  color: #fff;
  border: none; border-radius: 100px;
  font-size: 15px; font-weight: 600;
  cursor: pointer;
  box-shadow: var(--brand-shadow-sm);
  transition: box-shadow 0.15s, filter 0.15s;
}
.fission-form-panel .ff-primary:hover {
  filter: brightness(1.04);
  box-shadow: var(--brand-shadow);
}
.fission-form-panel .ff-primary:active {
  box-shadow: var(--glass-shadow-sm);
  filter: brightness(0.97);
}
.fission-form-panel .ff-locked-hint {
  font-size: 12px;
  color: var(--neu-text-muted);
  text-align: center;
  padding: 4px 0;
}
.fission-form-panel .ff-reset {
  width: 100%;
  padding: 12px 16px;
  background: var(--neu-bg-1);
  color: #c64545;
  border: none; border-radius: 14px;
  font-size: 14px; font-weight: 500;
  cursor: pointer;
  box-shadow: 4px 4px 8px var(--neu-shadow-raised-dark),
              -4px -4px 8px var(--neu-shadow-raised-light);
  transition: box-shadow 0.15s, filter 0.15s;
}
.fission-form-panel .ff-reset:hover { filter: brightness(0.98); }
.fission-form-panel .ff-reset:active {
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
}
/* 重置表单（仅解锁，非破坏）：中性强调色，区别于红色的「重置项目」 */
.fission-form-panel .ff-unlock {
  width: 100%;
  padding: 12px 16px;
  background: var(--neu-bg-1);
  color: var(--neu-accent);
  border: none; border-radius: 14px;
  font-size: 14px; font-weight: 500;
  cursor: pointer;
  box-shadow: 4px 4px 8px var(--neu-shadow-raised-dark),
              -4px -4px 8px var(--neu-shadow-raised-light);
  transition: box-shadow 0.15s, filter 0.15s;
}
.fission-form-panel .ff-unlock:hover { filter: brightness(0.98); }
.fission-form-panel .ff-unlock:active {
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
}

/* 顶部选项卡：直接裂变 / 案例裂变（拟态分段控件；两 tab 表单结构不同；锁定后禁切） */
.fission-form-panel .ff-tabs {
  display: flex; gap: 8px;
  margin-bottom: 18px;
  padding: 6px;
  border-radius: 14px;
  background: var(--neu-bg-1);
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
}
.fission-form-panel .ff-tab {
  flex: 1;
  padding: 9px 12px;
  border: none; border-radius: 10px;
  background: transparent;
  color: var(--neu-text-secondary);
  font-size: 14px; font-weight: 500; font-family: inherit;
  cursor: pointer;
  transition: box-shadow 0.15s, color 0.15s, background 0.15s;
}
.fission-form-panel .ff-tab:hover { color: var(--neu-text-primary); }
.fission-form-panel .ff-tab.active {
  color: var(--neu-accent);
  font-weight: 600;
  background: var(--neu-bg-1);
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
}
.fission-form-panel .ff-tab:disabled { opacity: .5; cursor: not-allowed; }

/* 案例裂变「需要裂变的素材」：从项目里选已有图的按钮（中性，区别于上传框；窄于主按钮） */
.fission-form-panel .ff-pick-project {
  margin-top: 8px;
  padding: 8px 14px;
  background: var(--neu-bg-1);
  color: var(--neu-accent);
  border: none; border-radius: 12px;
  font-size: 13px; font-weight: 500; font-family: inherit;
  cursor: pointer;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  transition: box-shadow 0.15s, filter 0.15s;
}
.fission-form-panel .ff-pick-project:hover { filter: brightness(0.98); }
.fission-form-panel .ff-pick-project:active {
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
}

/* locked 视觉：仅深一档凹陷，光标可进、可选可复制 */
.fission-form-panel.locked .ff-textarea,
.fission-form-panel.locked .ff-count {
  background: var(--neu-bg-2);
  color: var(--neu-text-secondary);
  cursor: text;
}
.fission-form-panel.locked .ff-uploader {
  cursor: not-allowed;
  pointer-events: none;
  opacity: 0.55;
}

/* 中栏占位 */
.fission-center-placeholder { flex: 1; display: flex; align-items: center; justify-content: center; padding: 40px 20px; text-align: center; }
.fission-placeholder-text { color: var(--neu-text-muted); font-size: 14px; max-width: 320px; line-height: 1.6; }

/* PCS（product-card-form）：未提交表单前隐藏对话框/聊天区（旧门禁，保持不动） */
.workspace-style-product-card-form:not(.product-card-set-locked) .chat-log,
.workspace-style-product-card-form:not(.product-card-set-locked) .composer { display: none !important; }
.workspace-style-product-card-form.product-card-set-locked .fission-center-placeholder { display: none !important; }

/* fission：对话框/聊天区始终可见；占位仅在"对话为空"时居中显示（提示去看左侧表单），
   此时隐藏聊天区，避免与 chat-view 的通用 empty-state 双重提示。conversation-empty 由 chat-view 统一切换。 */
.workspace-style-fission-form:not(.conversation-empty) #fissionCenterPlaceholder { display: none !important; }
.workspace-style-fission-form.conversation-empty .chat-log { display: none !important; }
/* fission：当前会话生成中时锁定「开始生图」按钮（即使表单已被「重置表单」解锁也保持锁定），
   与右侧对话框工作时变「停止」同理——一次生成没跑完不能再发起。session-working 由 chat-view 统一切换。 */
.workspace-style-fission-form.session-working .ff-primary { pointer-events: none; opacity: .55; cursor: not-allowed; }

/* ── 项目内图片选择弹窗（案例裂变「从项目中选择」跑赢图）── */
.modal-card.wip-card {
  width: min(720px, 92vw);
  max-width: 92vw;
  text-align: left;
}
.wip-card .modal-title { text-align: center; }
.wip-card .modal-text { text-align: center; margin-bottom: 12px; }
.wip-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 12px;
  max-height: 56vh;
  overflow-y: auto;
  padding: 4px;
}
.wip-empty {
  grid-column: 1 / -1;
  text-align: center;
  color: var(--neu-text-muted);
  font-size: 14px;
  padding: 40px 20px;
}
.wip-cell {
  position: relative;
  display: flex; flex-direction: column;
  padding: 0; border: 2px solid transparent; border-radius: 12px;
  background: var(--neu-bg-1);
  cursor: pointer;
  overflow: hidden;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.wip-cell img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  display: block; background: var(--neu-bg-2);
}
.wip-cell .wip-name {
  font-size: 11px; color: var(--neu-text-secondary);
  padding: 5px 6px; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wip-cell .wip-check {
  position: absolute; top: 6px; right: 6px;
  width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; color: #fff; background: var(--neu-accent);
  opacity: 0; transform: scale(0.6); transition: opacity 0.12s, transform 0.12s;
}
.wip-cell.selected { border-color: var(--neu-accent); }
.wip-cell.selected .wip-check { opacity: 1; transform: scale(1); }
.wip-cell.wip-broken img { opacity: 0.3; }

/* 选择器导航：面包屑 + 返回 */
.wip-toolbar {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px;
}
.wip-back {
  flex: 0 0 auto;
  padding: 6px 12px;
  border: none; border-radius: 10px;
  background: var(--neu-bg-1); color: var(--neu-text-secondary);
  font-size: 13px; font-family: inherit; cursor: pointer;
  box-shadow: 3px 3px 6px var(--neu-shadow-raised-dark),
              -3px -3px 6px var(--neu-shadow-raised-light);
}
.wip-back:hover:not(:disabled) { color: var(--neu-text-primary); }
.wip-back:disabled { opacity: .4; cursor: not-allowed; }
.wip-crumb {
  flex: 1 1 auto; min-width: 0;
  font-size: 12px; color: var(--neu-text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* 文件夹卡片（可点进入，区别于图片 cell） */
.wip-folder {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px;
  aspect-ratio: 1 / 1;
  padding: 8px; border: none; border-radius: 12px;
  background: var(--neu-bg-1); cursor: pointer;
  box-shadow: inset 3px 3px 6px var(--neu-shadow-inset-dark),
              inset -3px -3px 6px var(--neu-shadow-inset-light);
  transition: filter 0.15s;
}
.wip-folder:hover { filter: brightness(0.98); }
.wip-folder .wip-folder-ico { font-size: 38px; line-height: 1; }
.wip-folder .wip-name {
  font-size: 12px; color: var(--neu-text-secondary); max-width: 100%;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ===== 千川操作台 (qianchuanoperation.html) ===== */
/* ⚠ 千川这一整片（到文件末尾）的配色不再走 :root，而是走下面 .qc-body 里重定义的那份 token。
   改颜色请改那一块，别在这里逐条写死颜色 —— 那会让千川再次和主站分叉。 */
.qc-body { color: var(--text); margin: 0; min-height: 100vh; }
.qc-root { max-width: 720px; margin: 0 auto; padding: 24px 20px 64px; }
.qc-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; }
.qc-brand { display: flex; align-items: center; gap: 8px; font-size: 18px; font-weight: 700; color: var(--text); }
.qc-brand i { color: var(--brand); font-size: 22px; }
.qc-home { display: inline-flex; align-items: center; gap: 4px; color: var(--muted); text-decoration: none; font-size: 14px; padding: 6px 10px; border-radius: 8px; }
.qc-home:hover { background: var(--bg-2); color: var(--text); }
.qc-card { background: var(--panel); border: 1px solid var(--line); border-radius: 20px; box-shadow: var(--shadow); padding: 28px; }
.qc-loading { color: var(--muted); text-align: center; padding: 24px 0; }
.qc-status { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; color: var(--muted); margin-bottom: 12px; }
.qc-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.qc-dot-gray { background: #b0b4ba; }
.qc-dot-green { background: #34a853; box-shadow: 0 0 0 3px rgba(52,168,83,0.15); }
.qc-h2 { font-size: 22px; margin: 0 0 10px; color: var(--text); }
.qc-h3 { font-size: 15px; margin: 22px 0 10px; color: var(--text); display: flex; align-items: center; gap: 8px; }
.qc-count { background: var(--brand-soft); color: var(--brand); font-size: 12px; font-weight: 700; border-radius: 999px; padding: 1px 9px; }
.qc-muted { color: var(--muted); font-size: 14px; line-height: 1.7; margin: 0 0 14px; }
/* 计数旁的「数据不全」标记：条数少了一整类时不能还是灰色的，那和正常态一模一样 */
.qc-muted.qc-warn { color: #b45309; font-weight: 600; cursor: help; }
.qc-hint { color: var(--muted); font-size: 12.5px; margin: 14px 0 0; }
.qc-error { color: #d93025; font-size: 14px; margin: 0 0 14px; }
.qc-code { background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; font-size: 13px; color: var(--text); overflow-x: auto; margin: 0 0 18px; white-space: pre-wrap; word-break: break-all; }
.qc-btn { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--line-strong); background: var(--panel); color: var(--text); font: inherit; font-size: 14px; font-weight: 600; padding: 11px 20px; border-radius: 12px; cursor: pointer; transition: background .15s, border-color .15s, box-shadow .15s; }
.qc-btn:hover:not(:disabled) { background: var(--bg-2); }
.qc-btn:disabled { opacity: .55; cursor: not-allowed; }
.qc-btn-primary { background: var(--brand); border-color: var(--brand); color: #fff; }
.qc-btn-primary:hover:not(:disabled) { background: var(--brand-2); box-shadow: var(--shadow-hover); }
.qc-btn-ghost { background: transparent; color: var(--muted); }
.qc-meta { display: flex; flex-direction: column; gap: 8px; background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; margin: 4px 0 4px; }
.qc-meta-row { display: flex; align-items: baseline; gap: 10px; font-size: 13.5px; flex-wrap: wrap; }
.qc-meta-row > span { color: var(--muted); min-width: 130px; }
.qc-meta-row > b { color: var(--text); font-variant-numeric: tabular-nums; }
.qc-meta-row > em { color: var(--muted); font-style: normal; font-size: 12px; }
.qc-adv-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.qc-adv-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; }
.qc-adv-name { font-size: 14px; color: var(--text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qc-adv-id { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; flex-shrink: 0; }
.qc-empty { margin: 6px 0 0; }
.qc-actions { display: flex; gap: 12px; margin-top: 24px; flex-wrap: wrap; }

/* ===== 千川操作台 · 控制台外壳 ===== */
.qc-root { max-width: 1180px; }
.qc-appbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 4px 0 16px; flex-wrap: wrap; }
.qc-appbar-right { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.qc-adv { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.qc-select { font: inherit; font-size: 13px; padding: 6px 10px; border: 1px solid var(--line-strong); border-radius: 8px; background: var(--panel); color: var(--text); max-width: 240px; }
.qc-balance { font-size: 13px; color: var(--text); font-weight: 600; }
.qc-pill { display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 13px; font-weight: 600; padding: 7px 14px; border-radius: 999px; border: 1px solid var(--line-strong); background: var(--panel); color: var(--text); cursor: pointer; }
.qc-pill-blue { background: var(--brand); border-color: var(--brand); color: #fff; }
.qc-pill-green { background: rgba(52,168,83,.12); border-color: rgba(52,168,83,.4); color: #1e7e34; }
.qc-pill-gray { color: var(--muted); cursor: default; }
/* 顶栏「刷新」：清服务端取数缓存后重挂当前 tab。圆形、跟 .qc-pill 同高（33px），不抢眼。 */
.qc-refresh { display: inline-flex; align-items: center; justify-content: center; width: 33px; height: 33px; padding: 0; border-radius: 50%; border: 1px solid var(--line-strong); background: var(--panel); color: var(--muted); cursor: pointer; font-size: 16px; }
.qc-refresh:hover:not(:disabled) { background: var(--bg-2); color: var(--text); }
.qc-refresh:disabled { cursor: default; opacity: .7; }
.qc-refresh.spinning i { animation: qcSpin .8s linear infinite; }
@keyframes qcSpin { to { transform: rotate(360deg); } }
.qc-demo-banner { display: flex; align-items: center; gap: 8px; background: #fff8e1; border: 1px solid #ffe082; color: #8a6d00; border-radius: 10px; padding: 9px 14px; font-size: 13px; margin-bottom: 14px; }
.qc-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin-bottom: 18px; flex-wrap: wrap; }
.qc-tab { display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 14px; font-weight: 600; color: var(--muted); background: none; border: none; border-bottom: 2px solid transparent; padding: 10px 16px; cursor: pointer; }
.qc-tab:hover { color: var(--text); }
.qc-tab.active { color: var(--brand); border-bottom-color: var(--brand); }
.qc-panel { min-height: 300px; }

/* 工具条 / 分段 / 输入 */
.qc-toolbar { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.qc-toolbar-right { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.qc-toolbar-left { display: flex; align-items: center; gap: 10px; }
.qc-seg { display: inline-flex; border: 1px solid var(--line-strong); border-radius: 10px; overflow: hidden; }
.qc-seg button { font: inherit; font-size: 13px; padding: 7px 16px; background: var(--panel); border: none; color: var(--muted); cursor: pointer; }
.qc-seg button + button { border-left: 1px solid var(--line); }
.qc-seg button.active { background: var(--brand); color: #fff; }
/* 工具栏下面那一排（推广方式分段控件 + 判定口径说明）。刻意和 .qc-toolbar 分开：
   它是「看哪一批」的切换，不是「对这一批做什么」的动作。 */
.qc-subbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: -4px 0 12px; }
.qc-subbar-note { font-size: 12px; }
.qc-seg .qc-seg-n { opacity: .65; font-variant-numeric: tabular-nums; }
.qc-check-inline { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
/* 局部压掉全局 input{width:100%;padding:12px 14px;border-radius:16px;background:#fff}（styles.css 顶部第 63 行），
   否则原生复选框会被撑成一个大白圆角块、把标签文字挤到最右缘。
   与 .adm-audience-list 那处是同一个失效模式（2026-07-10 修过一次，这个通用工具类当时漏了）。 */
.qc-check-inline input[type="checkbox"] {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  padding: 0;
  margin: 0;
  border-radius: 3px;
}
.qc-date { font-size: 13px; color: var(--muted); display: inline-flex; align-items: center; gap: 4px; }
.qc-date input { font: inherit; padding: 5px 8px; border: 1px solid var(--line-strong); border-radius: 8px; background: var(--panel); color: var(--text); }
.qc-input { font: inherit; font-size: 14px; padding: 9px 12px; border: 1px solid var(--line-strong); border-radius: 10px; background: var(--panel); color: var(--text); width: 100%; box-sizing: border-box; }
/* 统计窗口快捷档（最长那档＝上游硬顶 180 天，没有更长的可选） */
.qc-presets { display: inline-flex; gap: 4px; }
.qc-presets button { font: inherit; font-size: 12px; padding: 4px 9px; border: 1px solid var(--line-strong); border-radius: 999px; background: var(--panel); color: var(--muted); cursor: pointer; }
.qc-presets button:hover { color: var(--text); border-color: var(--accent, #4c6ef5); }
.qc-btn-sm { padding: 6px 12px; font-size: 13px; }
.qc-btn-danger { color: #d93025; border-color: rgba(217,48,37,.35); }
.qc-btn-danger:hover:not(:disabled) { background: rgba(217,48,37,.08); }
.qc-icon-btn { border: 1px solid var(--line-strong); background: var(--panel); color: var(--muted); width: 30px; height: 30px; border-radius: 8px; cursor: pointer; font-size: 18px; line-height: 1; }
.qc-icon-btn:hover { color: #d93025; }
.qc-count { font-size: 13px; }

/* 表格 */
.qc-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; }
/* 限高（主列表表格 opt-in，见 qc-ui.js 的 maxHeight/TABLE_MAX_H）。表头吸顶靠的就是这里：
   下面 .qc-table thead th 早就写了 position:sticky，但容器不限高时滚动口和内容一样高，永远没有可吸的边。
   刻意只作用在 .qc-table-scroll 上 —— 展开里的嵌套子表、弹窗里的人群表、后台手写表一律不受影响。 */
.qc-table-wrap.qc-table-scroll { overflow-y: auto; overscroll-behavior: contain; scrollbar-gutter: stable; }
/* border-collapse 下 th 的下边框属于合并后的网格，吸顶时会跟表头脱开 → 用 inset 阴影画在 th 自己盒内。
   z-index 是必须的：不加会被行 hover 背景和单元格里的缩略图盖住。 */
.qc-table-wrap.qc-table-scroll .qc-table thead th { z-index: 2; box-shadow: inset 0 -1px 0 var(--line); }
/* ⚠ 只加字号、不加 padding/行高 —— 表格密度是明确要求，且被单测钉着 */
.qc-table { width: 100%; border-collapse: collapse; font-size: 13.5px; background: var(--panel); }
.qc-table th, .qc-table td { padding: 10px 12px; text-align: left; white-space: nowrap; border-bottom: 1px solid var(--line); }
.qc-table thead th { background: var(--bg-2); color: var(--muted); font-weight: 600; position: sticky; top: 0; }
.qc-table tbody tr:hover { background: var(--bg-2); }
.qc-table td:not(:first-child), .qc-table th:not(:first-child) { font-variant-numeric: tabular-nums; }
.qc-th-sort { cursor: pointer; user-select: none; }
.qc-th-sort:hover { color: var(--brand); }
.qc-arrow { color: var(--brand); font-weight: 700; }
.qc-th-check, .qc-td-check { width: 34px; text-align: center; }
.qc-td-empty { text-align: center; color: var(--muted); padding: 28px 0; }
.qc-rate-good { color: #1e7e34; font-weight: 700; }
.qc-rate-mid { color: #b8860b; font-weight: 700; }
.qc-rate-bad { color: #d93025; font-weight: 700; }

/* Excel 式逐列筛选：表头漏斗按钮 + 弹出面板（面板附在 body，fixed 定位） */
.qc-th-filter { margin-left: 6px; border: none; background: transparent; color: var(--muted); cursor: pointer; padding: 2px 4px; border-radius: 5px; font-size: 12px; line-height: 1; vertical-align: middle; }
.qc-th-filter:hover { color: var(--brand); background: var(--panel); }
.qc-th-filter.active { color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
/* 弹层自己是 flex 列：标题/搜索/全选/操作条固定，只有列表那一段伸缩并滚动。
   placePopover 空间不够时会给弹层压 max-height —— 压的必须是列表，否则整个弹层长出
   第二条滚动条，「清除/应用」被推到看不见的地方（弹层滚+列表滚的双滚动条）。 */
.qc-colfilter-pop { background: var(--panel); border: 1px solid var(--line-strong); border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.18); padding: 12px; min-width: 210px; max-width: min(360px, calc(100vw - 24px)); font-size: 13px; color: var(--text); display: flex; flex-direction: column; }
.qc-colfilter-title { font-size: 12.5px; color: var(--muted); margin-bottom: 8px; flex: none; }
.qc-colfilter-title b { color: var(--text); }
.qc-colfilter-num { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.qc-colfilter-num .qc-select { width: 76px; }
.qc-colfilter-num .qc-input { width: 88px; }
.qc-colfilter-search { margin-bottom: 8px; flex: none; }
.qc-colfilter-allrow { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); padding: 4px 2px; border-bottom: 1px solid var(--line); margin-bottom: 4px; cursor: pointer; flex: none; }
/* min-height:0 是让它在被压缩时真的能缩（flex 项默认最小尺寸=内容高，不写就压不动） */
.qc-colfilter-list { max-height: min(46vh, 360px); overflow-y: auto; display: flex; flex-direction: column; gap: 1px; flex: 1 1 auto; min-height: 0; }
/* ⚠ flex:none 不能删。列表是 flex 列且限高，而本项带 overflow:hidden ——
   overflow 非 visible 会把 min-height:auto 解析成 0，于是每一行被 flex-shrink 压扁去凑那个高度。
   2026-07-27 浏览器实测：50 个候选值时行高 6.0px、24 个时 7.4px（字号 12.5px），文字被纵向切掉大半，
   候选值越多压得越狠 —— 用户报的「下面的东西特别多，筛选界面会比较挤」就是这个。
   同一条规则链也压着 .qc-multipick-item（素材多选 picker 继承本类），一处修两处好。 */
.qc-colfilter-item { display: flex; align-items: center; gap: 6px; font-size: 12.5px; padding: 3px 2px; cursor: pointer; white-space: nowrap; overflow: hidden; flex: none; }
.qc-colfilter-item:hover { background: var(--bg-2); border-radius: 4px; }
/* 长值省略号 + title 兜底：原来只有 overflow:hidden 硬切，既没省略号也没 tooltip，
   「兴韵店-G100-7.24-混剪-任-2.mp4」这类名字看不出被截了。 */
.qc-colfilter-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; min-width: 0; }
.qc-colfilter-pop input[type="checkbox"] { width: 15px; height: 15px; flex: none; margin: 0; }
.qc-colfilter-bar { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; flex: none; }

/* 素材标签（上游 tags/tag，只读）：表格里的 chip + 工具栏那个独立筛选控件 */
.qc-tags { display: inline-flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.qc-tag { display: inline-block; padding: 1px 7px; border-radius: 999px; background: var(--bg-2); border: 1px solid var(--line); font-size: 11.5px; line-height: 17px; color: var(--text); white-space: nowrap; }
.qc-tagfilter { display: flex; align-items: center; gap: 6px; }
.qc-tagfilter .qc-input { width: 130px; }
.qc-btn.qc-tagbtn.active { color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
/* 按标签对比：基准行（「全部素材」）加重底色，它是分母 */
.qc-tag-base td { background: var(--bg-2); font-weight: 600; }
.qc-tag-name { display: inline-flex; align-items: center; gap: 6px; }


/* 数据报表 →「汇总」面板：总体合计 + 按标签对比。壳沿用 .qc-weight-panel，里面分两段。 */
.qc-sum-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; font-weight: 600; color: var(--text); }
.qc-sum-head i { color: var(--brand); }
.qc-sum-head-2 { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.qc-sum-head .qc-muted { font-weight: 400; }
.qc-sum-sub { font-size: 11.5px; font-weight: 400; color: var(--muted); }
.qc-sum-tag-mat { margin-top: 8px; }

/* 表单 / 建单 */
.qc-form { max-width: 620px; display: flex; flex-direction: column; gap: 14px; }
.qc-field { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--muted); }
.qc-field > span { font-weight: 600; }
.qc-field .qc-select { max-width: none; }
.qc-form-row { display: flex; gap: 14px; }
.qc-form-row .qc-field { flex: 1; }
.qc-mat-pick { display: flex; flex-wrap: wrap; gap: 8px; }
.qc-mat-pick:not(:empty) { margin-top: 8px; }
.qc-mat-chip { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line-strong); border-radius: 999px; padding: 4px 6px 4px 4px; font-size: 12.5px; color: var(--text); background: var(--panel); max-width: 260px; }
.qc-mat-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qc-mat-chip .qc-mat-thumb-ph, .qc-mat-chip img { width: 22px; height: 22px; border-radius: 999px; object-fit: cover; flex: none; display: flex; align-items: center; justify-content: center; font-size: 11px; }
.qc-chip-x { border: none; background: transparent; color: var(--muted); font-size: 15px; line-height: 1; padding: 0 2px; cursor: pointer; flex: none; }
.qc-chip-x:hover { color: #d64545; transform: none; }
/* 局部压掉全局 input{width:100%;padding:12px 14px;border-radius:16px;background:#fff}（styles.css 顶部第 63 行）。
   .qc-mat-chip 现在不再自带复选框（已改成下拉多选 picker），但这个 chip 是通用工具类，
   规则留着防下次有人往里塞复选框又踩同一个坑 —— 这个失效模式已经复发过三次
   （.adm-audience-list 2026-07-10、.qc-check-inline 与本处 2026-07-26/27）。 */
.qc-mat-chip input[type="checkbox"] {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  padding: 0;
  margin: 0;
  border-radius: 3px;
}
/* 「点开是个多选下拉」的触发按钮：长得像 select，但它是 button（要塞缩略图与计数） */
.qc-picker-btn { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; text-align: left; font: inherit; font-size: 14px; cursor: pointer; }
.qc-picker-btn:hover { transform: none; }
.qc-picker-btn:disabled { cursor: default; opacity: .7; }
/* 多选 picker 的行：缩略图 + 名称 + 右侧次要信息 */
.qc-multipick { min-width: 320px; }
.qc-multipick-list { max-height: 320px; }
.qc-multipick-item { gap: 8px; padding: 4px 2px; }
.qc-multipick-item .qc-mat-thumb-ph, .qc-multipick-item img { width: 28px; height: 28px; border-radius: 6px; object-fit: cover; flex: none; display: flex; align-items: center; justify-content: center; }
.qc-multipick-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; }
.qc-multipick-meta { flex: none; font-size: 11.5px; }

/* 加权面板 */
.qc-weight-panel { background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 16px; margin-bottom: 14px; }
.qc-weight-head { font-size: 13px; color: var(--muted); margin-bottom: 12px; }
.qc-weight-rows { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.qc-weight-row { display: flex; align-items: center; gap: 8px; }
.qc-weight-name { flex: 1; font-size: 13px; }
.qc-weight-val { width: 72px; }
.qc-weight-dir { max-width: 110px; }

/* 规则圈选 */
.qc-rule-logic { font-size: 13px; color: var(--muted); margin: 10px 0; display: flex; gap: 16px; align-items: center; }
.qc-rule-logic label { display: inline-flex; align-items: center; gap: 5px; }
.qc-cond { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.qc-cond .qc-select { max-width: 160px; }
.qc-cond-op { max-width: 70px; }
.qc-cond-val { width: 120px; }
.qc-rule-bar { display: flex; align-items: center; gap: 10px; margin-top: 14px; flex-wrap: wrap; }

/* ===== 投放管理重构：展开行 / 行内操作 / 单内素材下钻 / 素材详情 ===== */
/* 展开列 */
.qc-th-expand, .qc-td-expand { width: 30px; text-align: center; padding-left: 6px; padding-right: 0; }
.qc-expand-btn { border: none; background: transparent; color: var(--muted); cursor: pointer; font-size: 12px; line-height: 1; padding: 4px; border-radius: 6px; transition: color .15s, background .15s; }
.qc-expand-btn:hover { color: var(--brand); background: var(--panel); }
.qc-expand-btn.expanded { color: var(--brand); }

/* 明细展开行 */
.qc-detail-row > td { padding: 0; background: var(--bg-2); }
.qc-detail-row:hover { background: var(--bg-2); }
.qc-detail { padding: 14px 18px; }
.qc-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.qc-detail-title { font-size: 13px; font-weight: 600; color: var(--text); display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* 口径说明：单内素材的指标是「今日」而不是上方日期区间，必须写在表头旁边，不然数字会被误读 */
.qc-detail-hint { display: block; width: 100%; margin-top: 4px; font-size: 12px; font-weight: 400; font-style: normal; color: var(--muted); line-height: 1.5; }
.qc-detail-head-sub { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--border, #e5e7eb); }
.qc-detail-empty { padding: 8px 0 2px; }

/* 行内操作列 */
.qc-th-actions, .qc-td-actions { text-align: right; white-space: nowrap; }
.qc-td-actions { display: flex; gap: 4px; justify-content: flex-end; }
.qc-row-btn { display: inline-flex; align-items: center; gap: 4px; border: 1px solid var(--line-strong); background: var(--panel); color: var(--muted); cursor: pointer; font: inherit; font-size: 13px; padding: 5px 8px; border-radius: 8px; transition: color .15s, border-color .15s, background .15s; }
.qc-row-btn:hover { color: var(--brand); border-color: var(--brand); }
.qc-row-btn.qc-row-ok:hover { color: #1e7e34; border-color: rgba(52,168,83,.5); background: rgba(52,168,83,.08); }
.qc-row-btn.qc-row-danger:hover { color: #d93025; border-color: rgba(217,48,37,.4); background: rgba(217,48,37,.08); }

/* 单内素材卡片网格 */
.qc-mat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
.qc-mat-card { display: flex; gap: 10px; padding: 10px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; }
.qc-mat-thumb { position: relative; width: 56px; height: 56px; flex-shrink: 0; border-radius: 8px; overflow: hidden; }
.qc-mat-thumb img { width: 100%; height: 100%; object-fit: cover; }
.qc-mat-thumb-ph { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: var(--bg-2); color: var(--muted); font-size: 22px; }
.qc-mat-thumb-ph.lg { width: 160px; height: 160px; font-size: 44px; }
.qc-mat-badge { position: absolute; left: 3px; bottom: 3px; font-size: 10px; padding: 1px 5px; border-radius: 5px; background: rgba(0,0,0,.55); color: #fff; }
.qc-mat-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.qc-mat-name { font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qc-mat-spec { font-size: 11.5px; color: var(--muted); }
.qc-mat-metrics { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.qc-mat-metrics .qc-rate-good, .qc-mat-metrics .qc-rate-bad { font-weight: 700; }
.qc-mat-actions { display: flex; flex-direction: column; gap: 4px; flex-shrink: 0; }

/* 建单内嵌面板 */
.qc-create-panel { margin-bottom: 14px; border: 1px solid var(--line); border-radius: 12px; padding: 16px; background: var(--bg-2); }

/* 报表素材聚焦条 */
.qc-focus-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; background: rgba(93,83,174,.10); border: 1px solid rgba(93,83,174,.28); color: var(--text); border-radius: 10px; padding: 8px 14px; font-size: 13px; margin-bottom: 14px; }
.qc-focus-bar span { display: inline-flex; align-items: center; gap: 6px; }


/* 报表分页条 */
.qc-pager { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 12px 2px 2px; font-size: 13px; color: var(--muted); }
.qc-pager-info b { color: var(--text); }
.qc-pager-info em { font-style: normal; font-size: 12px; opacity: .75; }
.qc-pager-size { display: inline-flex; align-items: center; gap: 6px; }
.qc-pager-size .qc-select { width: auto; min-width: 72px; }
.qc-pager .qc-btn[disabled] { opacity: .45; cursor: not-allowed; }

/* 2026-07-28 删除 .qc-pick-*（追加素材那个手搓的平铺弹窗）：改走 .qc-multipick /
   .qc-colfilter-pop 那一套。顺带解决 .qc-pick-item 里的裸 checkbox 被全局
   input{width:100%} 撑爆的问题 —— 同族六处都有局部 override，只有它漏了。 */

/* 表格缩略图列（商品图 / 素材封面）：固定 40px 方块，签名 URL 失效时退化成占位图标 */
.qc-thumb { width: 40px; height: 40px; border-radius: 6px; object-fit: cover; display: block; background: var(--bg-2); }
.qc-thumb-empty { display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: 15px; }

/* 商品「在投计划」下钻里的子表 */
.qc-subtable-head { font-size: 12.5px; color: var(--text); margin-bottom: 8px; }
.qc-subtable { font-size: 12.5px; }
.qc-subtable th, .qc-subtable td { padding: 6px 10px; }

/* 素材详情弹窗 */
.qc-mat-detail { display: flex; gap: 14px; margin: 10px 0 4px; align-items: flex-start; }
.qc-mat-detail-thumb { flex-shrink: 0; border-radius: 10px; overflow: hidden; width: 116px; height: 116px; }
.qc-mat-detail-thumb img { width: 116px; height: 116px; object-fit: cover; border-radius: 10px; }
/* 封面缺失时的占位符要撑满这个 116 方块（.qc-thumb 本身是表格里的 40px） */
.qc-mat-detail-thumb .qc-thumb-empty { width: 100%; height: 100%; border-radius: 10px; font-size: 26px; }
.qc-mat-detail-meta { flex: 1; min-width: 0; }
@media (max-width: 560px) { .qc-mat-detail { flex-direction: column; } }
.qc-kv { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: 13px; border-bottom: 1px dashed var(--line); padding-bottom: 6px; }
.qc-kv span { color: var(--muted); }
.qc-kv b { color: var(--text); font-variant-numeric: tabular-nums; }

/* ===== 双台总开关 + 条件筛选 + 下钻工具 ===== */
.qc-console-switch { display: inline-flex; background: var(--bg-2); border: 1px solid var(--line-strong); border-radius: 999px; padding: 3px; gap: 2px; }
.qc-console-btn { display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 14px; font-weight: 600; color: var(--muted); background: none; border: none; padding: 8px 20px; border-radius: 999px; cursor: pointer; transition: background .15s, color .15s; }
.qc-console-btn:hover { color: var(--text); }
.qc-console-btn.active { background: var(--brand); color: #fff; }

.qc-filter-panel { background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; margin-bottom: 14px; }
.qc-filter-conds { margin: 4px 0 8px; }
.qc-detail-tools { display: flex; gap: 8px; }
.qc-detail-filter { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 12px 14px; margin-bottom: 10px; }

/* ===== 直播操作台 ===== */
.qc-live-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 12px; margin-bottom: 18px; }
.qc-live-card { background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 16px; }
.qc-live-val { font-size: 24px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.5px; }
.qc-live-label { font-size: 12px; color: var(--muted); margin-top: 6px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.qc-live-card-demo { background: var(--bg-2); border-style: dashed; }
.qc-demo-tag { font-size: 10px; padding: 1px 6px; border-radius: 6px; background: #fff3cd; color: #8a6d00; border: 1px solid #ffe082; }
.qc-live-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: #d93025; margin-right: 5px; animation: qcPulse 1.4s infinite; }
@keyframes qcPulse { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
.qc-live-control { margin-top: 4px; }
.qc-live-ctl-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 0; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.qc-live-ctl-row:last-child { border-bottom: none; }
.qc-live-ctl-name { font-size: 13px; font-weight: 600; color: var(--text); display: flex; flex-direction: column; gap: 3px; }
.qc-live-ctl-meta { font-size: 12px; color: var(--muted); font-weight: 400; }
.qc-live-ctl-btns { display: flex; gap: 6px; flex-wrap: wrap; }

/* 直播复盘：流量结构 + 漏斗 */
.qc-review-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 14px 0; }
@media (max-width: 720px) { .qc-review-grid { grid-template-columns: 1fr; } }
.qc-flow-row, .qc-funnel-row { display: flex; align-items: center; gap: 10px; margin: 9px 0; font-size: 13px; }
.qc-flow-name, .qc-funnel-stage { width: 76px; flex-shrink: 0; color: var(--muted); }
.qc-flow-bar { flex: 1; height: 12px; background: var(--bg-2); border-radius: 6px; overflow: hidden; }
.qc-flow-fill { display: block; height: 100%; background: var(--brand); border-radius: 6px; }
.qc-flow-pct { width: 44px; text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }
.qc-funnel-bar { flex: 1; height: 20px; background: var(--bg-2); border-radius: 6px; overflow: hidden; }
.qc-funnel-fill { display: block; height: 100%; background: linear-gradient(90deg, var(--brand), var(--brand-2)); border-radius: 6px; }
.qc-funnel-val { width: 140px; text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }
.qc-funnel-val em { color: var(--muted); font-style: normal; font-size: 12px; }
.qc-table-plain { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; margin-top: 6px; }
.qc-flow-abs { width: 92px; text-align: right; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* 档内明细：上游 flow_performance 给 17 个具体来源，归三档后把非零项排在条形下面 */
.qc-flow-items { display: flex; flex-wrap: wrap; gap: 6px; margin: -4px 0 10px 86px; }
.qc-flow-item { font-size: 11.5px; color: var(--muted); background: var(--bg-2); border-radius: 5px; padding: 2px 7px; }
.qc-flow-item b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
/* 复盘真正在看的两个结构（短视频引流 / 推荐feeds）提到三档之上，别埋在十几条明细里 */
.qc-flow-key { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.qc-flow-keyitem { display: flex; align-items: baseline; gap: 6px; background: var(--bg-2); border-radius: 8px; padding: 6px 10px; }
.qc-flow-keyitem em { font-style: normal; font-size: 11.5px; color: var(--muted); }
.qc-flow-keyitem b { font-size: 14px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.qc-flow-keyitem i { font-style: normal; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* 观看来源 / 成交来源（上游同一端点的两个 flow_source 口径） */
.qc-flow-modes { display: inline-flex; gap: 2px; margin-left: 10px; background: var(--bg-2); border-radius: 8px; padding: 2px; }
.qc-flow-mode { border: 0; background: transparent; color: var(--muted); font-size: 11.5px; font-weight: 500; padding: 3px 10px; border-radius: 6px; cursor: pointer; }
.qc-flow-mode.active { background: var(--panel); color: var(--text); box-shadow: var(--qc-raised-sm, 0 1px 2px rgba(0,0,0,.08)); }
.qc-h3-note { font-size: 12px; font-weight: 400; margin-left: 8px; }

/* 分小时走势（分直播间报表 dimension=HOURLY，已裁到本场时段） */
.qc-hourly-row { display: flex; align-items: center; gap: 10px; font-size: 12.5px; margin: 6px 0; }
.qc-hourly-time { width: 46px; flex-shrink: 0; color: var(--muted); font-variant-numeric: tabular-nums; }
.qc-hourly-bar { flex: 1; min-width: 60px; height: 10px; background: var(--bg-2); border-radius: 5px; overflow: hidden; }
.qc-hourly-fill { display: block; height: 100%; background: linear-gradient(90deg, var(--brand), var(--brand-2)); border-radius: 5px; }
.qc-hourly-val { width: 78px; text-align: right; font-variant-numeric: tabular-nums; color: var(--text); }
.qc-hourly-legend { font-size: 11.5px; margin-top: 10px; text-align: right; }

/* ===== 直播场次时间线（复盘 tab 的列表态） ===== */
.qc-tl-group { margin-bottom: 22px; }
.qc-tl-date { font-size: 13px; font-weight: 600; color: var(--muted); margin: 0 0 10px; display: flex; align-items: center; gap: 10px; }
.qc-tl-date::after { content: ''; flex: 1; height: 1px; background: var(--line); }
.qc-tl-count { font-weight: 400; font-size: 12px; order: 3; }
.qc-sess-card { display: flex; align-items: center; gap: 18px; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 14px 18px; margin-bottom: 10px; cursor: pointer; transition: border-color .15s, box-shadow .15s, transform .15s; }
.qc-sess-card:hover { border-color: var(--brand); box-shadow: var(--shadow); transform: translateY(-1px); }
.qc-sess-card:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.qc-sess-card.living { border-left: 3px solid #d93025; }
.qc-sess-card-main { flex: 1; min-width: 0; }
.qc-sess-card-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.qc-sess-card-title { font-size: 14px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qc-sess-card-meta { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 6px; font-size: 12px; color: var(--muted); }
.qc-sess-card-meta span { display: inline-flex; align-items: center; gap: 4px; }
.qc-sess-status { font-size: 12px; color: var(--muted); display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.qc-sess-status.living { color: #d93025; font-weight: 600; }
.qc-sess-metrics { display: flex; gap: 22px; flex-wrap: wrap; }
.qc-sess-metric { display: flex; flex-direction: column; gap: 2px; min-width: 68px; }
.qc-sess-metric em { font-style: normal; font-size: 11px; color: var(--muted); }
.qc-sess-metric b { font-size: 15px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.qc-sess-go { font-size: 12px; color: var(--brand); display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.qc-sess-empty { text-align: center; }

/* 选中来做多场对比。
   ⚠ 全站有一条 input { width: 100% }，原生复选框撞上它会被撑成一个大白块 —— 这个坑复发过四次
   （逐列筛选、多选 picker、人群目录、素材标签），所以每处放原生 checkbox 都要就地写死尺寸。 */
.qc-sess-pick { display: inline-flex; align-items: center; flex-shrink: 0; cursor: pointer; padding: 4px; }
.qc-sess-pick input[type="checkbox"] { width: 15px; height: 15px; min-width: 15px; margin: 0; accent-color: var(--brand); cursor: pointer; }

/* 「较上一场」：量按每小时折算后比，比率直接比（口径见列表上方的 ⓘ）。
   刻意不做红绿 —— 涨跌本身不等于好坏（消耗涨了不是坏事，也不是好事）。 */
.qc-sess-delta { font-style: normal; font-size: 11px; font-variant-numeric: tabular-nums; color: var(--muted); }
.qc-sess-delta.up::before { content: '↑'; margin-right: 1px; }
.qc-sess-delta.down::before { content: '↓'; margin-right: 1px; }
/* 「/h」＝这个百分比是每小时口径，不是拿旁边那个绝对值直接算的。不加下划线，只压小压淡。 */
.qc-sess-delta u, .qc-sess-insight u { text-decoration: none; font-size: 9.5px; opacity: .7; }

/* 判读：一场最多一句，后面跟着两个支撑数 */
.qc-sess-insight { display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; margin: 8px 0 0; font-size: 12.5px; color: var(--text); }
.qc-sess-insight-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--brand); flex-shrink: 0; }
.qc-sess-insight em { font-style: normal; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* 成交额归因：流量 × 转化率 × 客单价。是恒等式不是判读，所以压得比判读那行淡，排在它上面。 */
.qc-sess-attrib { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.qc-sess-attrib-eq { font-style: normal; opacity: .55; }
/* 总变化包一层，免得 pctText 里的 <u>/h</u> 变成独立 flex item 被 gap 推开 */
.qc-sess-attrib b { font-weight: 400; }
.qc-sess-attrib span + span::before { content: '×'; margin-right: 6px; opacity: .45; }
.qc-sess-attrib .lead { color: var(--text); font-weight: 600; }

/* 「这就是最好的一场」：切到最好场次基准时，基准自己不画一排 0%，改成一枚标记 */
.qc-sess-best { color: var(--brand); font-size: 11.5px; white-space: nowrap; }
/* 对照经营模型的达成数 */
.qc-sess-goal { font-size: 11.5px; padding: 1px 7px; border: 1px solid var(--line-strong); border-radius: 999px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.qc-sess-goal.ok { color: var(--brand); border-color: var(--brand); }

/* 分段开关（对比基准 / 模型的阶段页签） */
.qc-seg { display: inline-flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
.qc-seg-btn { padding: 5px 10px; border: 0; background: var(--panel); color: var(--muted); font-size: 12.5px; cursor: pointer; white-space: nowrap; }
.qc-seg-btn + .qc-seg-btn { border-left: 1px solid var(--line); }
.qc-seg-btn:hover { color: var(--text); }
.qc-seg-btn.active { background: var(--brand); color: #fff; }

/* 经营模型编辑器 */
.qc-model-picks { display: flex; align-items: flex-end; flex-wrap: wrap; gap: 12px; margin-bottom: 6px; }
.qc-model-pick { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--muted); }
.qc-model-pick select { min-width: 190px; }
.qc-model-note { font-size: 12.5px; margin: 0 0 12px; }
.qc-model-rows { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px 16px; }
.qc-model-row { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; }
.qc-model-label { color: var(--muted); display: flex; align-items: baseline; gap: 5px; }
.qc-model-label i { font-style: normal; font-size: 10.5px; opacity: .7; }
.qc-model-label b { font-weight: 400; font-size: 10.5px; padding: 0 5px; border: 1px solid var(--line-strong); border-radius: 999px; color: var(--muted); }
.qc-model-row em { font-style: normal; font-size: 11px; }
.qc-model-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }

/* 单场页的「对照模型」表 */
.qc-goal { margin-bottom: 16px; }
.qc-goal .qc-h3 { display: flex; align-items: center; gap: 8px; }
.qc-goal-score { margin-left: auto; font-size: 12px; font-weight: 400; padding: 1px 8px; border: 1px solid var(--line-strong); border-radius: 999px; color: var(--muted); font-variant-numeric: tabular-nums; }
.qc-goal-score.ok { color: var(--brand); border-color: var(--brand); }
.qc-goal-scroll { overflow-x: auto; }
.qc-goal-table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
.qc-goal-table th, .qc-goal-table td { padding: 7px 12px; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--line); }
.qc-goal-table thead th { color: var(--muted); font-weight: 600; }
.qc-goal-table tbody th[scope="row"] { text-align: left; font-weight: 400; color: var(--text); }
.qc-goal-table td { font-variant-numeric: tabular-nums; }
.qc-goal-table tr.na td, .qc-goal-table tr.na th { color: var(--muted); }
.qc-goal-main { margin-left: 8px; font-size: 10.5px; padding: 0 6px; border-radius: 999px; background: var(--brand); color: #fff; }

/* 多场对比：行=指标、列=场次的转置表 */
.qc-cmp { margin-bottom: 16px; }
.qc-cmp-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.qc-cmp-head .qc-h3 { margin: 0; }
.qc-cmp-scroll { overflow-x: auto; }
.qc-cmp-table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
.qc-cmp-table th, .qc-cmp-table td { padding: 7px 12px; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--line); }
.qc-cmp-table thead th { text-align: right; vertical-align: bottom; font-weight: 600; }
.qc-cmp-table tbody th[scope="row"] { text-align: left; color: var(--muted); font-weight: 400; }
.qc-cmp-table td { font-variant-numeric: tabular-nums; color: var(--text); }
.qc-cmp-date, .qc-cmp-title, .qc-cmp-sub { display: block; }
.qc-cmp-date { font-size: 11px; color: var(--muted); font-weight: 400; }
.qc-cmp-title { max-width: 190px; overflow: hidden; text-overflow: ellipsis; }
.qc-cmp-sub { font-size: 11px; color: var(--muted); font-weight: 400; }
.qc-cmp-group th { text-align: left; font-size: 11.5px; color: var(--brand); background: var(--bg-2); font-weight: 600; }
.qc-cmp-top { font-weight: 700; }

@media (max-width: 860px) {
  .qc-sess-card { flex-wrap: wrap; gap: 12px; }
  .qc-sess-metrics { width: 100%; gap: 16px; }
}

/* ===== 直播场次数据页（独立标签页 /qianchuan-live-session.html） ===== */
.qc-appbar-slim { justify-content: flex-start; gap: 18px; }
.qc-back { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); text-decoration: none; padding: 6px 10px; border-radius: 8px; }
.qc-back:hover { background: var(--bg-2); color: var(--text); }
.qc-sess-page { display: block; }
.qc-sess-hero { display: flex; align-items: center; gap: 18px; background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: 18px 20px; margin-bottom: 16px; }
.qc-sess-cover { width: 96px; height: 96px; border-radius: 12px; object-fit: cover; flex: none; }
.qc-sess-cover-empty { display: flex; align-items: center; justify-content: center; background: var(--bg-2); color: var(--muted); font-size: 30px; }
.qc-sess-hero-body { min-width: 0; }
.qc-sess-title { font-size: 20px; font-weight: 700; color: var(--text); margin: 0 0 8px; }
.qc-sess-hero-meta { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: var(--muted); }
.qc-sess-hero-meta span { display: inline-flex; align-items: center; gap: 4px; }
.qc-sess-toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; font-size: 12.5px; }
.qc-sess-toolbar .qc-muted { display: inline-flex; align-items: center; gap: 5px; }

/* ===== 素材数据页（/qianchuan-material.html）===== */
/* 封面复用 .qc-sess-cover 的方框，里面塞的是 thumbHtml 的 img 或占位块 */
.qc-mat-hero-cover { overflow: hidden; display: flex; align-items: center; justify-content: center; background: var(--bg-2); }
.qc-mat-hero-cover img { width: 100%; height: 100%; object-fit: cover; }
.qc-mat-hero-cover .qc-mat-thumb-ph.lg { width: 100%; height: 100%; font-size: 30px; }
/* 审核状态徽标：通过=绿、拒绝=红、其余中性 */
.qc-audit { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; padding: 2px 8px; border-radius: 6px; background: var(--bg-2); color: var(--muted); }
.qc-audit.ok { background: rgba(34, 160, 96, .12); color: #1f9e5f; }
.qc-audit.bad { background: rgba(214, 69, 69, .12); color: #d64545; }
/* 关联商品卡片网格 */
.qc-prod-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; margin-top: 6px; }
.qc-prod-card { display: flex; gap: 10px; align-items: center; border: 1px solid var(--line); border-radius: 12px; padding: 10px; background: var(--panel); }
.qc-prod-img { width: 56px; height: 56px; border-radius: 8px; object-fit: cover; flex: none; }
.qc-prod-img-ph { display: flex; align-items: center; justify-content: center; background: var(--bg-2); color: var(--muted); font-size: 22px; }
.qc-prod-body { min-width: 0; }
.qc-prod-name { font-size: 13px; color: var(--text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.qc-prod-meta { display: flex; gap: 8px; flex-wrap: wrap; font-size: 11.5px; color: var(--muted); margin-top: 4px; }
.qc-metric-group { margin-bottom: 18px; }
.qc-metric-group-title { font-size: 13px; font-weight: 600; color: var(--text); margin: 0 0 10px; display: flex; align-items: center; gap: 6px; }
.qc-metric-group-title i { color: var(--brand); }
.qc-live-card-derived { background: var(--bg-2); }
.qc-derived-mark { font-size: 10px; padding: 0 5px; border-radius: 5px; background: rgba(93,83,174,.14); color: var(--brand); border: 1px solid rgba(93,83,174,.3); cursor: help; }

/* ===== 详情弹窗外壳 + 每日趋势（2026-07-26 顶掉八大人群那块：上游没这个维度，删） ===== */
.qc-modal { max-width: 640px; width: 92vw; text-align: left; position: relative; }
.qc-modal-wide { max-width: 900px; }
/* 弹窗内容自己滚：200 天窗口的每日明细有 200 行，不封高会顶出视口。
   注意只在这一层滚 —— 里面的表格不再套 .qc-table-scroll，否则是滚动容器套滚动容器。 */
/* padding-right 给滚动条留位：不留的话最右一列指标卡的右边框紧贴滚动条，看着像被裁掉了 */
.qc-modal-body { margin-top: 4px; max-height: calc(100dvh - 210px); overflow-y: auto; overscroll-behavior: contain; padding-right: 8px; }
.qc-modal-x { position: absolute; top: 12px; right: 12px; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--muted); cursor: pointer; font-size: 15px; }
.qc-modal-x:hover { color: var(--text); border-color: var(--line-strong); }
/* 标题下面那行灰色小字：状态 · 营销目标 · 已投天数 · ID */
.qc-modal-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 2px 0 4px; font-size: 12.5px; color: var(--muted); }
.qc-modal-meta > span + span::before { content: '·'; margin-right: 10px; color: var(--line-strong); }
/* 次要字段：标签在上、值在下。原来一行两端对齐，900px 宽下标签贴左值贴右，配对全靠横扫 */
.qc-modal-kv { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px 18px; margin: 14px 0 4px; }
.qc-modal-kv .qc-kv { display: flex; flex-direction: column; align-items: flex-start; justify-content: flex-start; gap: 2px; border-bottom: 0; padding: 0; }
.qc-modal-kv .qc-kv span { font-size: 11.5px; line-height: 1.3; }
.qc-modal-kv .qc-kv b { font-size: 13.5px; font-weight: 600; }
@media (max-width: 720px) { .qc-modal-kv { grid-template-columns: repeat(2, 1fr); } }

/* 核心指标条：打开详情第一眼要看的四~六个数，字号明显大于次要字段 */
.qc-stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 10px; margin: 12px 0 2px; }
.qc-stat { background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.qc-stat-l { font-size: 11.5px; color: var(--muted); line-height: 1.2; }
.qc-stat-v { font-size: 19px; font-weight: 650; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.2px; line-height: 1.15; overflow-wrap: anywhere; }
/* ROI 着色必须比上一行更具体：.qc-rate-good 在本文件更早处定义，同特异性会被 .qc-stat-v 的 color 压掉 */
.qc-stat-v.qc-rate-good { color: #1e7e34; }
.qc-stat-v.qc-rate-bad { color: #d93025; }
/* 素材/商品详情里指标条挤在 116px 缩略图右边，auto-fit 会把第 6 张卡挤出容器 → 定死三列两排 */
.qc-mat-detail-meta .qc-stat-row { grid-template-columns: repeat(3, 1fr); margin-top: 0; }
@media (max-width: 560px) { .qc-mat-detail-meta .qc-stat-row { grid-template-columns: repeat(2, 1fr); } }

/* 每日趋势：柱子用纯 CSS 高度百分比画（CSP 只允许 script-src 'self'，不能引图表库） */
.qc-trend-section { margin-top: 20px; border-top: 1px solid var(--line); padding-top: 16px; }
.qc-trend-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 8px; }
.qc-trend-head .qc-h4 { margin: 0; font-size: 14px; font-weight: 600; color: var(--text); }
.qc-trend-win { font-size: 12px; font-weight: 400; margin-left: 8px; }
.qc-trend-tabs { display: flex; gap: 6px; margin-left: auto; }
.qc-trend-tabs .active { background: var(--brand); border-color: var(--brand); color: #fff; }
.qc-trend-demo { font-size: 12px; margin: 0 0 8px; }
.qc-trend-flat { padding: 24px 4px; }
.qc-trend-chart-wrap { margin-bottom: 16px; }
/* 合计/日均/峰值：光有柱子读不出量级，鼠标不放上去就什么都不知道 */
.qc-trend-stats { font-size: 12.5px; color: var(--muted); margin: 0 0 8px; }
.qc-trend-stats b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.qc-trend-stats i { margin: 0 7px; font-style: normal; color: var(--line-strong); }
.qc-trend-plot { position: relative; height: 150px; border-bottom: 1px solid var(--line); }
.qc-trend-bars { display: flex; align-items: flex-end; gap: 3px; height: 100%; }
.qc-trend-bar { flex: 1; min-width: 4px; position: relative; border-radius: 3px 3px 0 0; cursor: default; background: linear-gradient(to top, rgba(93,83,174,.45), var(--brand)); transition: opacity .15s ease; }
.qc-trend-bar:hover { opacity: .72; }
/* 峰值柱换色并把数值标在柱顶（天花板留了 12% 余量，标签不会被裁） */
.qc-trend-bar.is-peak { background: linear-gradient(to top, rgba(234,67,53,.5), #ea4335); }
.qc-trend-peak { position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); margin-bottom: 3px; font-size: 10.5px; font-weight: 600; color: #c5221f; white-space: nowrap; }
/* 日均参考线：一眼看出哪几天在平均线以上 */
.qc-trend-mean { position: absolute; left: 0; right: 0; border-top: 1px dashed rgba(60,64,67,.4); pointer-events: none; }
.qc-trend-mean span { position: absolute; right: 0; bottom: 2px; font-size: 10.5px; color: var(--muted); background: var(--panel); padding: 0 4px; border-radius: 4px; }
/* 日期刻度单独一行、与柱子同 flex 布局，天然对齐（原来塞在柱子里绝对定位） */
.qc-trend-axis { display: flex; gap: 3px; margin-top: 5px; }
.qc-trend-tick { flex: 1; min-width: 4px; font-size: 10.5px; color: var(--muted); text-align: center; white-space: nowrap; overflow: visible; }
/* 明细表：弹窗里的表不限高（沿用「嵌套/弹窗表不套滚动容器」的约定），加浅斑马纹压住行错位 */
.qc-trend-table .qc-table tbody tr:nth-child(even) { background: rgba(0,0,0,.015); }
.qc-trend-table .qc-table tbody tr:hover { background: var(--bg-2); }
.qc-trend-wd { font-style: normal; color: var(--muted); font-size: 11.5px; margin-left: 4px; }

/* ============================================================
   千川操作台 · 水马智能视觉体系（2026-07-27）
   ============================================================
   由来：千川这一整片原本是扁平 Google 风（白底 / 1px 细线 / #1a73e8），
   主站是 Weave neumorphic（蓝灰渐变底 / 凸起内凹软阴影 / #5580cc）。
   两套并存已经夹生 —— 千川用的【全站】弹窗 .modal-card 和 toast 早就是
   neumorphic 的，但弹窗里装的表格和按钮还是白底细线，打开任意详情弹窗就能看见那条接缝。

   做法：不逐条重写上面那 387 条 .qc-* 规则（其中 260 处走 var()），
   而是在 .qc-body 作用域里把 token 重新指向 --neu-*，规则自动跟着换皮；
   下面再补一批【形状】覆写（凸起 / 内凹 / 渐变）—— 换色换不出软阴影。

   ⚠ .qc-body 就是 <body> 元素本身，所以挂到 document.body 上的浮层
     （逐列筛选弹层 / openModal 的 overlay / toast 容器）也在作用域内，不必另处理。
   ⚠ 全站 :root 一个字没动 —— 主站 landing / 工作台 / 后台不受影响。
   ⚠ 表格的行高 / 字号 / 分隔线【刻意不动】：十几列的报表要保持可扫，
     只换容器和表头。单测钉死，别顺手「统一」成大行距。
   ============================================================ */

/* ---- ① token 重映射（改颜色就改这里）---- */
.qc-body {
  --panel: var(--neu-bg-1);
  --bg: var(--neu-bg-1);
  --bg-2: var(--neu-bg-2);
  --text: var(--neu-text-primary);
  /* ⚠ 用 --neu-text-secondary 而不是 --neu-text-muted：千川满屏是口径说明小字，
     两档里必须挑深的那档。（换肤前 muted 是 #9aa8c0，在蓝灰底上只有约 2.4:1。） */
  --muted: var(--neu-text-secondary);
  --brand: var(--neu-accent);
  --brand-2: var(--neu-brand-start);
  --brand-soft: rgba(93,83,174,.12);
  /* ⚠ 刻意不用 --neu-line（alpha .15 太淡）：表格保留紧凑高对比是明确要求，分隔线得看得见。 */
  --line: rgba(120,130,170,.35);
  --line-strong: rgba(120,130,170,.55);
  --shadow: 5px 5px 12px var(--neu-shadow-raised-dark), -5px -5px 12px var(--neu-shadow-raised-light);
  --shadow-hover: 7px 7px 16px var(--neu-shadow-raised-dark), -7px -7px 16px var(--neu-shadow-raised-light);
  /* 本片自用的几组阴影/渐变，省得每条规则抄一长串 */
  --qc-raised: 5px 5px 12px var(--neu-shadow-raised-dark), -5px -5px 12px var(--neu-shadow-raised-light);
  --qc-raised-sm: 3px 3px 6px var(--neu-shadow-raised-dark), -3px -3px 6px var(--neu-shadow-raised-light);
  --qc-inset: inset 3px 3px 6px var(--neu-shadow-inset-dark), inset -3px -3px 6px var(--neu-shadow-inset-light);
  --qc-inset-sm: inset 2px 2px 4px var(--neu-shadow-inset-dark), inset -2px -2px 4px var(--neu-shadow-inset-light);
  --qc-grad: linear-gradient(145deg, var(--neu-brand-start), var(--neu-brand-end));
  --qc-grad-shadow: 4px 4px 10px rgba(40,133,239,.35), -3px -3px 8px var(--neu-shadow-raised-light);
  --qc-grad-pressed: inset 3px 3px 6px rgba(60,90,170,.35), inset -3px -3px 6px rgba(255,255,255,.22);
  background: var(--page-bg);
  font-family: 'Noto Sans SC', system-ui, -apple-system, BlinkMacSystemFont, "PingFang SC", "HarmonyOS Sans SC", "Microsoft YaHei", sans-serif;
}

/* ⚠ 全局 button:hover{transform:translateY(-1px)}（本文件第 61 行）在密集工具栏里会让
   一整排按钮跟着鼠标抖。千川作用域内关掉，hover 改用阴影表达（凸起→内凹）。
   整块可点的卡片例外，下面单独放开。 */
.qc-body button:hover, .qc-body button:active { transform: none; }

/* ---- ② 凸起：卡片与容器 ---- */
.qc-card,
.qc-table-wrap,
.qc-sess-hero,
.qc-sess-card,
.qc-mat-card,
.qc-live-card,
.qc-prod-card {
  border: none;
  box-shadow: var(--qc-raised);
}
.qc-card { border-radius: 20px; }
.qc-table-wrap, .qc-sess-hero { border-radius: 16px; }
.qc-sess-card, .qc-mat-card, .qc-live-card, .qc-prod-card { border-radius: 14px; box-shadow: var(--qc-raised-sm); }
.qc-body .qc-sess-card:hover { transform: translateY(-2px); box-shadow: var(--qc-raised); }
/* 示例卡的「虚线」信号：border:none 之后 border-style:dashed 就失效了，改用 outline 保住区分度 */
.qc-live-card-demo { outline: 1px dashed var(--line-strong); outline-offset: -1px; }

/* ---- ③ 浮层：必须和同色背景拉开 ----
   neumorphic 最典型的翻车点就是浮层与底色同色、边界看不出来。
   所以这里不是软阴影，而是真投影 + 一圈内描白线。 */
.qc-colfilter-pop {
  border: none;
  border-radius: 14px;
  background: var(--neu-bg-1);
  box-shadow: 0 16px 40px rgba(42,58,88,.22), 0 2px 8px rgba(42,58,88,.14),
              inset 0 0 0 1px rgba(255,255,255,.55);
}

/* ---- ④ 内凹：输入框、统计卡、说明块 ---- */
.qc-input,
.qc-select,
.qc-date input,
.qc-stat,
.qc-weight-panel,
.qc-meta,
.qc-code,
.qc-adv-item,
.qc-table-plain,
.qc-filter-panel,
.qc-detail-filter,
.qc-create-panel {
  border: none;
  background: var(--neu-bg-1);
  box-shadow: var(--qc-inset-sm);
}
.qc-input, .qc-select, .qc-date input { border-radius: 12px; }
.qc-stat, .qc-table-plain, .qc-detail-filter, .qc-adv-item { border-radius: 12px; }
.qc-weight-panel, .qc-meta, .qc-code, .qc-filter-panel, .qc-create-panel { border-radius: 14px; }
.qc-input:focus, .qc-select:focus, .qc-date input:focus {
  outline: none;
  box-shadow: var(--qc-inset-sm), 0 0 0 2px rgba(93,83,174,.32);
}
/* 表头做成浅内凹槽。⚠ 第二条不能省：限高表格的表头为了吸顶用 box-shadow 画下边框
   （见上文 .qc-table-scroll 那段注释），特异性更高，只改第一条的话它会变回平的。 */
.qc-table thead th { box-shadow: var(--qc-inset-sm); }
.qc-table-wrap.qc-table-scroll .qc-table thead th { box-shadow: inset 0 -1px 0 var(--line), var(--qc-inset-sm); }
.qc-table tbody tr:hover { background: rgba(93,83,174,.07); }
.qc-trend-table .qc-table tbody tr:nth-child(even) { background: rgba(42,58,88,.035); }

/* ---- ⑤ 按钮：凸起 → hover 内凹 ---- */
.qc-btn,
.qc-refresh,
.qc-icon-btn,
.qc-row-btn,
.qc-modal-x,
.qc-presets button,
.qc-home,
.qc-back {
  border: none;
  background: var(--neu-bg-1);
  box-shadow: var(--qc-raised-sm);
  transition: box-shadow .18s ease, color .18s ease, background .18s ease;
}
.qc-btn { border-radius: 12px; }
/* 按钮标签不许拦腰折断。2026-07-27 实测 929px 宽时「新建投放单」被折成「新建投放/单」、
   「筛选」折成「筛/选」，整条工具栏跟着长高一倍 —— 工具栏是 flex-wrap，该换行的是按钮之间，
   不是按钮内部。这是换皮前就有的老毛病，顺手修掉。 */
.qc-btn, .qc-pill, .qc-row-btn, .qc-presets button, .qc-seg button, .qc-console-btn, .qc-tab { white-space: nowrap; }
.qc-btn:hover:not(:disabled),
.qc-refresh:hover:not(:disabled),
.qc-row-btn:hover,
.qc-modal-x:hover,
.qc-presets button:hover,
.qc-home:hover,
.qc-back:hover {
  background: var(--neu-bg-1);
  color: var(--neu-accent);
  box-shadow: var(--qc-inset-sm);
}
.qc-btn:disabled, .qc-refresh:disabled { box-shadow: var(--qc-inset-sm); }
/* 语义色的 hover 不能被上面那条通用规则洗掉：删除是红的、启用是绿的，这是信息层级 */
.qc-icon-btn:hover { color: #d93025; box-shadow: var(--qc-inset-sm); }
.qc-row-btn.qc-row-ok:hover { color: #1e7e34; background: rgba(52,168,83,.10); box-shadow: var(--qc-inset-sm); }
.qc-row-btn.qc-row-danger:hover { color: #d93025; background: rgba(217,48,37,.10); box-shadow: var(--qc-inset-sm); }
.qc-btn-danger { color: #d93025; }
.qc-btn-danger:hover:not(:disabled) { color: #c5221f; background: rgba(217,48,37,.10); box-shadow: var(--qc-inset-sm); }
/* 主按钮 / 主色药丸：渐变 + 彩色投影，hover 变内凹（按下去的手感） */
.qc-btn-primary, .qc-pill-blue {
  background: var(--qc-grad);
  border: none;
  color: #fff;
  box-shadow: var(--qc-grad-shadow);
}
.qc-btn-primary:hover:not(:disabled), .qc-pill-blue:hover {
  background: var(--qc-grad);
  color: #fff;
  box-shadow: var(--qc-grad-pressed);
}
.qc-btn-ghost { background: transparent; box-shadow: none; }
.qc-btn-ghost:hover:not(:disabled) { background: transparent; color: var(--neu-accent); box-shadow: var(--qc-inset-sm); }

/* ---- ⑥ 分段 / 开关：内凹槽 + 凸起滑块 ---- */
.qc-console-switch, .qc-seg {
  border: none;
  background: var(--neu-bg-1);
  box-shadow: var(--qc-inset);
  padding: 4px;
  gap: 3px;
  overflow: visible;
}
.qc-console-switch { border-radius: 999px; }
.qc-seg { border-radius: 12px; display: inline-flex; }
.qc-seg button { background: transparent; border: none; border-radius: 9px; color: var(--muted); }
.qc-seg button + button { border-left: none; }
.qc-seg button.active, .qc-console-btn.active {
  background: var(--qc-grad);
  color: #fff;
  box-shadow: 3px 3px 7px rgba(40,133,239,.32), -2px -2px 6px var(--neu-shadow-raised-light);
}
/* tab 条保持下划线式，只跟着换色：tab 又多又窄，做成凸起 chip 会挤成一团 */
.qc-tab.active { border-bottom-color: var(--brand); }

/* ---- ⑦ 药丸 / 标记 / 提示条 ---- */
.qc-pill, .qc-tag, .qc-mat-chip, .qc-audit, .qc-derived-mark, .qc-demo-tag,
.qc-demo-banner, .qc-focus-bar { border: none; }
.qc-pill { background: var(--neu-bg-1); box-shadow: var(--qc-raised-sm); }
.qc-pill-gray { box-shadow: var(--qc-inset-sm); }
.qc-pill-green { background: rgba(52,168,83,.14); color: #1e7e34; box-shadow: var(--qc-inset-sm); }
.qc-tag, .qc-mat-chip { background: var(--neu-bg-2); box-shadow: var(--qc-inset-sm); }
.qc-demo-tag { background: rgba(240,176,96,.20); color: #8a6d00; }
.qc-derived-mark { background: rgba(93,83,174,.14); }
.qc-demo-banner { background: rgba(240,176,96,.16); color: #8a6d00; border-radius: 12px; box-shadow: var(--qc-inset-sm); }
.qc-focus-bar { background: rgba(93,83,174,.10); border-radius: 12px; box-shadow: var(--qc-inset-sm); }

/* ---- ⑧ 顶栏品牌块：水马智能主品牌 + 千川副标 ---- */
/* 结构见 qianchuan-controller.js 的 shellHtml()。图标块抄 .landing-brand-icon。 */
.qc-brand-group { display: flex; align-items: center; gap: 10px; min-width: 0; }
.qc-brandmark {
  width: 34px; height: 34px; border-radius: 10px; flex: none;
  background: var(--qc-grad); color: #fff; font-size: 19px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 3px 3px 7px rgba(40,133,239,.32), -2px -2px 6px var(--neu-shadow-raised-light);
}
.qc-brandname { font-size: 17px; font-weight: 700; color: var(--neu-text-hero); letter-spacing: .5px; white-space: nowrap; }
.qc-brand-sep { width: 1px; height: 18px; background: var(--line-strong); flex: none; }
.qc-brand-sub { display: inline-flex; align-items: center; gap: 5px; font-size: 13.5px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.qc-brand-sub i { font-size: 16px; color: var(--brand); }
.qc-home { padding: 7px 13px; border-radius: 999px; gap: 5px; }
.qc-home span { white-space: nowrap; }
.qc-back { border-radius: 999px; padding: 7px 13px; }
/* ⚠ 断点刻意压到很窄才生效。第一版按视口宽度写了 1120/920，但 .qc-root 的 max-width 是
   1180px —— 内容区宽度被容器封顶，跟视口没关系，于是在 1440 的屏上「返回」文字照样被藏掉，
   等于把用户明确要的那行字白删了。实测顶栏本来就会折成两行（品牌+台切换 / 账户上下文），
   那是够用的排法，所以不靠藏文字去凑一行，只在真正的手机宽度才收。 */
@media (max-width: 720px) { .qc-home span { display: none; } .qc-home { padding: 7px 10px; } }
@media (max-width: 560px) { .qc-brand-sep, .qc-brand-sub { display: none; } }

/* ---- ⑨ 授权页（/qianchuanlogin.html）---- */
/* 复用站内现成的 .auth-screen / .auth-card / .auth-brand（本文件 Phase 2 那一段），
   不再自己搭一套；这里只补「让 .qc-root 居中」和按钮的 neu 化。 */
.qc-auth-page .qc-root { max-width: none; min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.qc-auth-page .auth-card { padding: 38px 34px; }
/* 副标题与品牌块左对齐（.auth-brand 是左对齐的，副标题居中会明显错位） */
.qc-auth-sub { display: flex; align-items: center; gap: 6px; }
.qc-auth-sub i { color: var(--neu-accent); font-size: 17px; }
.qc-auth-actions { display: flex; flex-direction: column; gap: 12px; margin-top: 20px; }
.qc-auth-page .primary-btn, .qc-auth-page .ghost-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; padding: 13px 22px; border: 0; border-radius: 14px;
  font-size: 14.5px; font-weight: 600;
  transition: box-shadow .18s ease, color .18s ease;
}
.qc-auth-page .primary-btn { background: var(--qc-grad); color: #fff; box-shadow: var(--qc-grad-shadow); }
.qc-auth-page .primary-btn:hover { background: var(--qc-grad); box-shadow: var(--qc-grad-pressed); }
.qc-auth-page .ghost-btn { background: var(--neu-bg-1); color: var(--neu-text-secondary); box-shadow: var(--qc-raised-sm); }
.qc-auth-page .ghost-btn:hover { color: var(--neu-accent); box-shadow: var(--qc-inset-sm); }
.qc-auth-page .primary-btn:disabled, .qc-auth-page .ghost-btn:disabled { opacity: .6; cursor: not-allowed; }
/* ⚠ .auth-error 在本文件第 517 行是 display:none（登录表单靠 JS 开关它）。
   千川授权页是「有就渲染、没有就不渲染」，所以这里必须显式放开，否则提示条永远不出现。 */
.qc-auth-page .auth-error { display: block; margin-bottom: 4px; font-size: 13.5px; line-height: 1.6; }
.qc-auth-page .auth-error.qc-auth-warn {
  background: rgba(240,176,96,.16); color: #8a6d00;
  box-shadow: inset 2px 2px 4px rgba(200,140,50,.18);
}

/* ===============================================================
   千川操作台 · 事实胶囊与 ⓘ 口径弹层（2026-07-27）
   ===============================================================
   由来：用户「网页里面有太多的诸如『这个账户的素材还没有标签。标签在千川后台的素材管理里打
   （开放平台只给读和筛，没有写标签的接口），打完回来点右上角「刷新」即可。』这一种打补丁性的
   句子了……都去了」。全台扫出 35 处左右，同一句话在三个地方各写了一份。

   处置分两档，这里是承载它们的两个新组件：
     · .qc-facts / .qc-fact  —— 表格上方那两三行长句压成的胶囊，只放事实（哪个窗口、多少行、
       其中多少有消耗）。一个字的解释都不放。
     · .qc-info / .qc-info-pop —— 「不写就会读错数」的口径句收进来，按需展开（见 qc-ui.js
       的 attachInfo）。解释「我们为什么做不到」的那些**不往这里搬，是直接删掉**。
   =============================================================== */

.qc-facts { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 8px 0 2px; }
.qc-fact {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px; border-radius: 999px;
  background: var(--neu-bg-1); box-shadow: var(--qc-inset-sm);
  font-size: 12px; color: var(--muted); white-space: nowrap;
}
/* 数据不全的警告（已截断 / 有几次取数失败）刻意**不进 ⓘ**：藏起来就等于骗人说数据是全的。
   它留在胶囊行里常驻，只是换成琥珀，明细才进 ⓘ。 */
.qc-fact-warn { color: #8a6d00; box-shadow: inset 2px 2px 4px rgba(200,140,50,.20); }

.qc-info {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0; flex: none;
  border: none; border-radius: 50%;
  background: transparent; color: var(--muted);
  font-size: 15px; line-height: 1; cursor: pointer;
  transition: color .15s ease, box-shadow .15s ease;
}
.qc-info:hover { color: var(--brand); box-shadow: var(--qc-inset-sm); }
.qc-info i { font-size: 15px; }

/* 弹层挂在 body 下、和内容同底色，所以和逐列筛选弹层一样必须靠真投影 + 内描白线画出边界，
   光靠 neumorphic 的软阴影会和背景糊在一起。定位/翻转/夹边全走 placePopover。 */
.qc-info-pop {
  position: fixed; max-width: 340px; padding: 12px 14px;
  border: none; border-radius: 14px; background: var(--neu-bg-1);
  box-shadow: 0 16px 40px rgba(42,58,88,.22), 0 2px 8px rgba(42,58,88,.14),
              inset 0 0 0 1px rgba(255,255,255,.55);
  font-size: 12.5px; line-height: 1.65; color: var(--muted);
}
.qc-info-pop ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 7px; }
.qc-info-pop li { position: relative; padding-left: 13px; }
.qc-info-pop li::before { content: ''; position: absolute; left: 0; top: 8px; width: 5px; height: 5px; border-radius: 50%; background: var(--line-strong); }

/* 空状态：一句现状 + 一个动作。原来这里是一整段「为什么是空的」的解释。 */
.qc-empty { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 34px 20px; text-align: center; }
.qc-empty-line { display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--muted); }
.qc-empty-line i { font-size: 17px; color: var(--line-strong); }

/* 素材库页脚那行「标题与直播间片段在投放管理里看」。原来它套在 .qc-src-note 那个虚线框里，
   一个纯指路的链接却做成了警示框的样子。 */
.qc-mat-types-note { margin: 14px 0 0; font-size: 12px; color: var(--muted); }
.qc-mat-types-note a { color: var(--brand); text-decoration: none; border-bottom: 1px solid rgba(93,83,174,.35); }
.qc-mat-types-note a:hover { border-bottom-color: var(--brand); }
/* 多选弹层里的「没有可选项」（同上，原来也是虚线框） */
.qc-multipick-empty { margin: 0; padding: 14px 4px; text-align: center; font-size: 12.5px; }

/* ===== 素材评级 ===== */
/* 名字着色。刻意只染文字不加底色：一列底色铺下来，表格会变成一面红绿墙，反而看不出重点。
   未起量用灰＋不加粗 —— 它是「还没有结论」，不该和「差」抢注意力。 */
.qc-name-good { color: #1e7e34; font-weight: 700; }
.qc-name-bad { color: #d93025; font-weight: 700; }
.qc-name-unspent { color: var(--muted); }

/* 评级设置弹层 */
.qc-grade-head { margin: 0 0 14px; font-size: 13px; color: var(--muted); line-height: 1.7; }
.qc-grade-head b { color: var(--text); }
.qc-grade-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.qc-grade-col { border: 1px solid var(--border); border-radius: 10px; padding: 12px 14px; }
.qc-grade-col h4 { margin: 0 0 10px; font-size: 13.5px; display: flex; align-items: baseline; gap: 8px; }
.qc-grade-col h4 .qc-muted { font-size: 11.5px; font-weight: 400; }
.qc-grade-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; font-size: 13px; }
/* ⚠ 必须限宽：全站 input{width:100%}，不写这一条这几个数字框会各占满一整行，
   把「标签 : 输入框」那一行撑成两行（原生控件被 width:100% 撑爆已复发四次）。 */
.qc-grade-row input { width: 96px; flex: none; text-align: right; }
@media (max-width: 640px) { .qc-grade-grid { grid-template-columns: 1fr; } }

/* 素材详情页的等级徽章 */
.qc-grade-badge { margin-top: 10px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; font-size: 12.5px; }
.qc-grade-badge b { font-size: 13.5px; }
.qc-grade-badge span { color: var(--muted); }


/* ============================================================
   玻璃皮肤 · 终端覆写块（2026-08-03）
   ============================================================
   基准：水马网页UI设计方向/AquaHorse Homepage Options.dc.html

   为什么是「文件末尾一整块」而不是就地改上面那 113 条规则：
   ① 本仓库【没有构建步骤】⇒ 没有 autoprefixer。就地改意味着 -webkit-backdrop-filter
      要手写一百多遍；写在这里只写几遍。
   ② 上面那 180 多条双向阴影并不同形 —— 有 8 条尾部挂着【焦点环】、34 条带品牌色。
      逐条正则重写最容易悄悄洗掉焦点环（无障碍回退，且没有任何测试抓得到）。
      这里【一条都不改】，只在最后覆盖真正可见的那些表面；没被覆盖到的，
      靠 :root 里 --neu-shadow-*-light: transparent 已经退化成柔和的单向投影，不会突兀。
   同特异性 + 更靠后 ⇒ 自然胜出，不需要 !important（少数几条例外见 ⑤）。

   ★★ 分层不变量：一个元素只有在【最近的玻璃祖先就是页面本身】时才允许带 backdrop-filter。
      设计稿就是这么做的 —— 每个 backdrop-filter 都直接压在 mesh 上，
      卡片内部的输入框一律是无模糊的半透明（.dc.html:136/143/534）。
      照这个分层写，「模糊套模糊」在结构上就不可能发生，而不是靠人盯着。

   ★★ 另外三条硬规则：
      · 滚动容器不加 blur（.chat-log / .file-list / .qc-table-wrap）—— 每帧都要重拍背景快照；
      · 重复列表行不加 blur（会话项 / 文件项 / 表格行）—— 层数随数据量线性涨；
      · 页面级容器不加 blur（html/body/.app-shell/.workspace-layout）—— 这条还有正确性理由：
        backdrop-filter 会给 position:fixed 后代造出【包含块】，顶栏和移动端抽屉会当场错位。
        backend/test/qianchuan-visual-theme.test.js 里有断言钉着这条。
   ============================================================ */

/* ---- ① T2：玻璃面。直接压在页面 mesh 上，唯一一层 blur ---- */
.landing-version-pill,
.feature-card,
.landing-screen .ghost-btn,
.pricing-screen .back-btn,
.pricing-card,
.auth-card,
.top-navbar,
.workspace-navbar,
.adm-topbar,
.adm-sidenav,
.adm-card,
.adm-login-card,
.pc-topbar,
.pc-card,
.cd-card,
.project-card,
.composer,
/* ⚠ 左右栏的 .panel-header【不在这一层】。侧栏本身是 transparent（:7031 明确列为「刻意不覆盖」），
   直接坐在页面 mesh 上 ⇒ 标题行是这块面的一部分，不是浮在它上面的独立卡片。
   给它描一圈 --glass-border（rgba(255,255,255,.38)）等于在侧栏顶部横一条白线：
   折叠按钮下面那条「奇怪的白线」就是它的下边框，「会话」那个太高的框就是它的 padding。 */
.fission-form-panel .ff-footer,
/* 中栏的两块 .panel（文件预览 / 案例视图）——.panel 这个类全站只命中这两个元素。
   ⚠ .center-panel 本身是 transparent、直接坐在页面 mesh 上 ⇒ 这一层是合法的 T2。
   不写成裸 .panel 是为了不误伤将来别处复用这个类。 */
.center-panel .panel,
.qc-card {
  background: var(--glass-fill);
  -webkit-backdrop-filter: var(--glass-blur);
  backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow);
}

/* 顶栏是横贯整幅的一条，只留下边界；模糊比常规面更重一点（设计稿 blur(20px)）。 */
.top-navbar,
.workspace-navbar,
.adm-topbar,
.pc-topbar {
  border: none;
  border-bottom: 1px solid var(--glass-border);
  border-radius: 0;
  -webkit-backdrop-filter: blur(20px) saturate(1.6);
  backdrop-filter: blur(20px) saturate(1.6);
}

/* ---- ② T2-flat：同款玻璃外观，但【不加 blur】 ----
   命中的是「面积小 / 数量多 / 已经在别的玻璃面里」的那批：再叠一层模糊既看不出来，
   又要多一个合成层。填充比 T2 稍实（.28），因为它们常常压在半透明父面上。 */
.pc-mini-btn,
.adm-back,
.adm-btn-view,
.adm-back-pill,
.adm-btn-soft,
.adm-records-loadmore-btn,
.adm-stack-card,
.project-rename-btn, .project-edit-desc-btn, .project-delete-btn,
.user-avatar-btn,
.toggle-btn,
.left-panel .panel-header-bar .toggle-btn,
.session-item,
.chat-header-actions .ghost-btn,
.attach-btn,
.right-panel .view-mode-switcher button, .view-mode-btn,
.file-upload-container .ghost-btn,
.batch-actions .ghost-btn,
.hamburger-btn,
.plan-option,
.fission-form-panel .ff-thumb,
.fission-form-panel .ff-reset,
.fission-form-panel .ff-unlock,
.fission-form-panel .ff-pick-project,
.wip-back,
/* ⚠ :not() 排除「填色」变体 —— 它们是白字，套上半透明玻璃底会当场变成隐形按钮。
   （.qc-btn-primary「新建投放单」就这么白过一次：底被洗成 rgba(255,255,255,.28)、
   字还是 #fff，对比度 1.04:1，界面上只剩一个空药丸。）填色变体统一在下面给渐变。 */
.qc-btn:not(.qc-btn-primary), .qc-refresh, .qc-icon-btn, .qc-row-btn, .qc-modal-x, .qc-presets button, .qc-home, .qc-back,
.qc-pill:not(.qc-pill-blue):not(.qc-pill-green),
.qc-auth-page .ghost-btn {
  background: var(--glass-fill-hi);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow-sm);
}

/* 模型下拉单独列一条、不并进上面那批 —— 上面用的是 background 简写，会把它右侧那个
   chevron 的 background-image 一起冲成 none（下拉就没箭头了）。这里只发 background-color。
   hover 同理，且要盖住 .project-model-select:hover 的旧内阴影（(0,3,0) > (0,2,0)）。 */
.chat-header-actions .project-model-select {
  background-color: var(--glass-fill-hi);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-shadow-sm);
}
.chat-header-actions .project-model-select:hover {
  background-color: var(--glass-fill-hi);
  border-color: var(--glass-border-hi);
  box-shadow: var(--glass-shadow-lg);
}

/* 填色按钮：白字必须配实底。全站统一走品牌渐变。 */
.qc-btn-primary, .qc-pill-blue {
  background: var(--brand-grad);
  border: none;
  color: #fff;
  box-shadow: var(--brand-shadow-sm);
}
.qc-btn-primary:hover:not(:disabled), .qc-pill-blue:hover {
  background: var(--brand-grad);
  box-shadow: var(--brand-shadow);
}

/* ---- ③ T2F：浮层。坐在遮罩上而不是页面 mesh 上 ----
   ⚠ 填充必须更实（.72）：.modal-overlay 是 rgba(20,28,50,.32) 的深色遮罩，
     0.20 的玻璃压上去会变成深板岩底配深色字（约 3:1，读不了）。
   ⚠ 同一时刻最多一个浮层可见 ⇒ 这里用最重的模糊不会有性能问题。 */
.modal-card,
.toast,
.user-dropdown,
.session-context-menu,
.context-menu,
.qc-colfilter-pop,
.qc-info-pop {
  background: var(--glass-fill-strong);
  -webkit-backdrop-filter: var(--glass-blur-lg);
  backdrop-filter: var(--glass-blur-lg);
  border: 1px solid var(--glass-border-hi);
  box-shadow: var(--glass-shadow-lg);
}
/* 遮罩提亮：原来的 rgba(42,58,88,.40) 太重，磨砂卡压上去读不出「磨砂」这件事 */
.modal-overlay { background: rgba(20, 28, 50, 0.32); }

/* ⚠ 用户下拉是 .top-navbar / .workspace-navbar 的 DOM 子节点，而那两条顶栏本身就带 blur
   ⇒ 它会违反「最近的玻璃祖先必须是页面」这条不变量，形成模糊套模糊。
   它的填充已经是 .72（接近实色），去掉 blur 视觉上几乎没差别，但少一个合成层。
   （其余浮层都挂在 document.body 下，不受影响。） */
.user-dropdown {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

/* ---- ④ T3：玻璃【内部】的输入框 / 凹槽 / 行。永不加 blur ----
   这一层的作用是「比父面稍亮一点的凹陷」，靠一条内高光而不是投影来表达。 */
.pc-select,
.pc-navitem.active,
.adm-toggle,
.adm-mini-stat,
.adm-action,
.adm-navitem.active,
.adm-login-form input,
.adm-ent-mrow,
.adm-aud-row,
.adm-invite-newform,
.adm-input,
.auth-card .auth-tabs,
.auth-card .auth-form input,
.auth-card .back-btn,
.auth-card .auth-tab.active,
.token-usage-badge,
.session-input-container input, #sessionLabel, #chatInput, #currentPath,
.composer textarea,
.current-path,
.file-staging .staging-item, .file-staging > div,
.msg.assistant,
.tool-call,
.subagent-step,
.modal-input,
.modal-actions .ghost-btn,
.fission-form-panel .ff-uploader,
.fission-form-panel .ff-textarea,
.fission-form-panel .ff-count,
.fission-form-panel .ff-select,
.fission-form-panel .ff-tendency-value,
.fission-form-panel .ff-tabs,
.fission-form-panel .ff-tab.active,
.wip-cell,
.wip-folder,
.qc-input, .qc-select, .qc-date input, .qc-stat, .qc-weight-panel, .qc-meta, .qc-code, .qc-adv-item,
.qc-console-switch, .qc-seg,
.qc-fact {
  background: var(--glass-fill-inset);
  border: 1px solid var(--glass-border);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

/* ---- ④b 上面那批里，真正能【输入】的那些要一条看得见的边 ----
   设计稿的输入框都压在彩色 mesh 上，白边看得见；本站大量输入框在近白的卡片/弹窗里，
   白边等于没有边框，用户找不到输入区在哪。展示型表面（.msg / .tool-call / .qc-stat /
   .token-usage-badge / .*-tab.active …）保持上面那条白边不变——它们不需要「可点击」的暗示。 */
.pc-select,
.adm-login-form input,
.adm-input,
.auth-card .auth-form input,
.session-input-container input, #sessionLabel, #chatInput, #currentPath,
.composer textarea,
.modal-input,
.fission-form-panel .ff-textarea,
.fission-form-panel .ff-count,
.fission-form-panel .ff-select,
.qc-input, .qc-select, .qc-date input {
  border-color: var(--glass-field-border);
}

/* ---- ⑤ 必须带 !important 才抢得回来的几条 ----
   上面 4000–4750 行那批 Phase 4/5 覆写用了 !important，同特异性下 !important 恒胜，
   所以这里逐条列出、逐条带上，而不是给整个块无脑加 —— 因为还有一批 !important
   是【状态信号】（选中 / 拖拽 / 危险），那些必须继续赢，见下一段。 */
.project-card { background: var(--glass-fill) !important; }
.user-avatar-btn { background: var(--glass-fill-hi) !important; }
.user-dropdown { background: var(--glass-fill-strong) !important; }
.token-usage-badge { background: var(--glass-fill-inset) !important; }
.msg.assistant { background: var(--glass-fill-inset) !important; }
.hamburger-btn { background: var(--glass-fill-hi) !important; }

/* ⚠ 刻意【不】覆盖的状态信号 —— 它们靠 !important 压住常规皮肤才有意义：
   .file-item.selected / .drag-over / .drag-over-folder（选中与拖放高亮）
   .session-item.active（当前会话）、.msg.user（用户气泡）、.danger-btn（危险动作）
   .resize-handle.dragging（正在拖）、桌面端 .right-panel{background:transparent!important}
   动它们等于把「选中」和「没选中」画成一个样。 */

/* ---- ⑤b 主/次按钮：全站统一成设计稿的「品牌渐变药丸 / 玻璃药丸」 ----
   设计稿里所有主动作按钮都是 linear-gradient(135deg,紫,蓝) + border-radius:100px + 紫色辉光
   （.dc.html:51/60/187/233/327/538）。原来是扁平 var(--brand) + 8px 圆角，
   只换颜色不换形状会显得半新不旧，所以形状一起收。
   ⚠ 例外：登录卡和弹窗里的提交键，设计稿用的是 12px 圆角矩形（.dc.html:138/147），下面单独放行。 */
.primary-btn, #newSessionBtn, #sendBtn {
  background: var(--brand-grad);
  color: #fff;
  border: none;
  border-radius: 100px;
  box-shadow: var(--brand-shadow-sm);
}
.primary-btn:hover, #newSessionBtn:hover, #sendBtn:hover {
  background: var(--brand-grad);
  box-shadow: var(--brand-shadow);
}
.primary-btn:disabled, #sendBtn:disabled {
  background: var(--brand-grad);
  box-shadow: none;
  opacity: .45;
}
.auth-card .auth-form .primary-btn,
.modal-actions .primary-btn { border-radius: 12px; }

.ghost-btn {
  background: var(--glass-fill-hi);
  border: 1px solid var(--glass-border);
  border-radius: 100px;
  box-shadow: var(--glass-shadow-sm);
  color: var(--text);
}

/* ---- ⑥ hover：设计稿【没有任何位移】，改用「填充变实 + 投影变深」表达 ----
   全局 button:hover{transform:translateY(-1px)}（本文件上方）在模糊面上每次 hover
   都会逼浏览器重拍一次背景快照，密集工具栏里肉眼可见地卡。玻璃面上一律关掉。
   ⚠ :hover 的特异性 (0,2,0) 高于上面几块的 (0,1,0)，所以这里必须重写一遍，
     否则上面那些 :hover 规则里的旧阴影会继续赢。 */
.feature-card:hover,
.pricing-card:hover,
.project-card:hover,
.adm-card:hover,
.pc-card:hover,
.cd-card:hover,
.session-item:hover,
.landing-screen .ghost-btn:hover,
.chat-header-actions .ghost-btn:hover,
.toggle-btn:hover,
.attach-btn:hover,
.qc-pill:hover {
  transform: none;
  background: var(--glass-fill-hi);
  border-color: var(--glass-border-hi);
  box-shadow: var(--glass-shadow-lg);
}
.project-card:hover { background: var(--glass-fill-hi) !important; }

/* ---- ⑥b 剩下几处还在用不透明底的 hover / 凹槽 ----
   都是「只在鼠标停上去时才出现」或「细长条」，之前给的是实色 var(--neu-bg-1)，
   压在 mesh 上会闪出一块白。改成半透明即可，不需要 blur（面积小 / 频繁重绘）。 */
.adm-navitem:hover,
.user-dropdown-item:hover,
.session-more-btn:hover,
.file-item:hover,
.adm-records-scroll {
  background: var(--glass-fill-inset);
}
/* 拖拽条：⚠【不许在这里画竖线】。分栏线由紧接着下面 ⑥c 的 .left-panel/.right-panel 画，
   拖动条再自画两条 inset，就和面板的棱叠成三四条挤在一起的平行线（用户报过一次）。
   它只是一块 12px 的透明命中区，视觉全交给 ::before 那根 hover 才出现的抓握杆。 */
.resize-handle {
  background: transparent;
  box-shadow: none;
}

/* ---- ⑥c 分栏的「玻璃棱」：一条冷灰实线 + 一条白高光，两条一起才有厚度 ----
   设计稿 .dc.html:155/191/295/331。桌面端 .left-panel/.right-panel 本来就是
   transparent !important（上方 Phase 4 覆写），所以这里只补边，不碰底色。 */
.workspace-layout .left-panel { box-shadow: inset -1px 0 0 var(--glass-divider-line), 1px 0 0 var(--glass-divider-light); }
.workspace-layout .right-panel { box-shadow: inset 1px 0 0 var(--glass-divider-line), -1px 0 0 var(--glass-divider-light); }
.pc-sidenav, .adm-sidenav, .fission-form-panel {
  box-shadow: inset -1px 0 0 var(--glass-divider-line), 1px 0 0 var(--glass-divider-light);
}

/* ---- ⑦ 不支持 backdrop-filter 时的兜底 ----
   ⚠ 只能用 @supports：自定义属性里的颜色不参与解析校验（存的是 token 流），
     所以 var() 的兜底机制在这里根本不会触发。
   没有模糊，半透明就只是「发灰」⇒ 直接把填充提到接近实色，保可读性优先。 */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  :root {
    --glass-fill: rgba(255, 255, 255, 0.72);
    --glass-fill-hi: rgba(255, 255, 255, 0.82);
    --glass-fill-strong: rgba(255, 255, 255, 0.94);
    --glass-fill-inset: rgba(255, 255, 255, 0.66);
  }
}
