/* =============================================================================
 * CAS · base-design.css  v1.1
 * 全站基础样式 / 设计令牌 / 通用组件
 * 作者：design team · 2026-05
 *
 * 引入方式：
 *   <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;600&display=swap" rel="stylesheet">
 *   <link rel="stylesheet" href="/static/css/base-design.css?v=5">
 *   <script src="/static/js/base-design.js?v=5" defer></script>
 *
 * 暗色页面：在 <body> 加 class="theme-dark"
 *
 * 命名约定：
 *   - 新写代码请优先使用 .cas-* 前缀类名与 --cas-* 变量
 *   - 旧类名（.btn / .card / .modal …）与短变量（--bg / --accent …）作为别名保留，
 *     现有 13 个页面无需大改即可继续工作
 *   - 状态色统一通过 CSS 变量 --cas-status-{entity}-{key}-{role} 暴露，
 *     base-design.js 负责从后端拉取并写入 :root
 *
 * ───────────────────────────────────────────────────────────────────────────
 *  目录（搜索 "* N." 即可跳转）
 *  注：§3 / §4 / §21 / §22 / §23 已下线（v1.1，0 引用），编号保留为占位
 *  以避免外部文档（CLAUDE.md / design-guide-v5.md）引用错乱。
 * ───────────────────────────────────────────────────────────────────────────
 *   0.  RESET / NORMALIZE                              ~ 57
 *   1.  DESIGN TOKENS · 亮色主题（:root 全局变量）       ~ 92    ← 改主色/字号/圆角/状态色
 *   2.  DESIGN TOKENS · 暗色主题（body.theme-dark）      ~ 213
 *   3.  ── 已下线（typography 工具类，0 引用）           ~ 240
 *   4.  ── 已下线（utility 工具类，0 引用）              ─
 *   5.  LAYOUT · body/sidebar/main/topbar/content       ~ 249
 *   6.  SIDEBAR                                         ~ 277
 *   7.  TOPBAR · credits-pill / avatar / back-btn       ~ 326
 *   8.  PAGE HEADER                                     ~ 376
 *   9.  TABS · 下划线型                                  ~ 395
 *   10. BUTTONS · 32/28/24 三档 + .cas-btn-approved 绿色 ~ 420   ← 改按钮高度/padding
 *   11. FORM CONTROLS · field 容器                        ~ 507
 *   12. FILTER BAR · cas-filter-outer / -bar / -right    ~ 541
 *   13. CARD / PANEL                                    ~ 626
 *   14. TABLES · 行高 / padding / hover / sortable       ~ 652   ← 改表格密度
 *   15. BADGE · 状态标签 + entity: project|media|tool 扩展  ~ 719
 *   16. MODAL · 三段式（header / body / footer）          ~ 780
 *   17. POPOVER · 列设置等浮层                            ~ 868
 *   18. DROPDOWN MENU · 头像/操作菜单                    ~ 882
 *   19. TOAST · 右上角通知                                ~ 908
 *   20. TOOLTIP · [data-tip="..."]                       ~ 936
 *   21. ── 已下线（skeleton / spinner，0 引用）           ─
 *   22. ── 已下线（pagination，0 引用）                  ─
 *   23. ── 已下线（empty state，0 引用）                 ─
 *   24. DIVIDER                                         ~ 959
 *   25. ANIMATION · 全站统一入场                          ~ 966
 *   26. PRINT                                           ~ 981
 *   27. BREADCRUMB · 面包屑导航                          ~ 992
 *   28. META BAR · 信息行（label/value）                 ~ 1000
 *   29. TOGGLE BUTTON · 表格展开/收起                    ~ 1008
 *   30. NESTED TABLE · 嵌套表格色彩规范                  ~ 1020
 *   31. SCROLLABLE TABLE · 可滚动表格（表头冻结）        ~ 1027
 *   32. TOOL PAGE · 工具页（双栏 gallery + control）     ~ 1037
 *   33. TD-LINK · 表格内可点击文本链接                   ~ 1057
 *   34. THUMB · 表格内缩略图（48×36 单一档）             ~ 1086
 * ───────────────────────────────────────────────────────────────────────────
 *  CHANGELOG
 *   v1.5 (2026-05-11) §15 Badge 修补：
 *                     · .cas-badge-on / .cas-badge-off / .badge-on / .badge-off 加进
 *                       主选择器列表（之前只设 color/bg 没继承 padding/border-radius/font-size，
 *                       导致"启用 / 停用"badge 是裸文字不是小药丸形状）
 *   v1.4 (2026-05-10) Session 7f 收尾：
 *                     · §10 新增 .cas-btn-success（绿描边透明底，与 cas-btn-danger 对仗，
 *                       用于"启用 / 启动"等正向操作；可叠加在 cas-btn-sm 等任一档）
 *   v1.3 (2026-05-10) Session 7e：
 *                     · §10 新增 .cas-btn-approved（24×11px 绿色，审批通过专用，
 *                       用 --cas-status-review-approved 变量）
 *                     · §15 新增 3 组 entity 扩展共 9 条 selector：
 *                       - project: personal（中性灰）/ team（accent 软色）
 *                       - media: image|video|text|audio（共用中性灰，data-status 仅语义占位）
 *                       - tool: new（accent 实色）/ soon（info 软色）/ maintenance（warning 软色）
 *                     · 配套 Session 7f：替换 .btn-approve-sm / .btn-reject-sm /
 *                       .media-badge / .type-badge / .badge-soon / .badge-maintenance /
 *                       .proj-type-badge 等自家 class 为 base 标准
 *   v1.2 (2026-05-10) Session 7d：
 *                     · §34 新增 .cas-thumb / .cas-thumb-empty 收编各页 .task-thumb /
 *                       .asset-thumb / .sub-thumb 重复定义（任务详情 .submit-ver-thumb
 *                       60×45 不属于此 class，保持独立）
 *   v1.1 (2026-05-10) Session 6a 体检收尾：
 *                     · 删 3 个死 token（accent-soft-2 / info-soft / warning-soft）
 *                     · §3 §4 §21 §22 §23 整节下线（0 引用），共 ~25 行 + ~50 行
 *                     · §8/§11/§25/§28 surgical 删 6 个无主类
 *                     · §12 .cas-filter-bar input 排除 [type=checkbox/radio]，
 *                       checkbox/radio 单独 13×13 + margin:0
 *                     · §33 td-link text-decoration-color 改 currentColor 25%（暗色友好）
 *   v1.0 (2026-05) 初版
 * ───────────────────────────────────────────────────────────────────────────
 * ============================================================================= */


/* =============================================================================
 *  0. RESET / NORMALIZE
 * ============================================================================= */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: 'Noto Sans SC', sans-serif;
  font-size: 13px;
  line-height: 1.5;
  color: var(--cas-text-primary);
  background: var(--cas-bg-base);
  scrollbar-gutter: stable; /* 滚动条始终占位，防止出现/消失时的横向位移 */
}
h1, h2, h3, h4, h5, h6, p, ul, ol, dl, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button, input, select, textarea {
  font-family: inherit; font-size: inherit; color: inherit;
}
button { cursor: pointer; background: none; border: none; padding: 0; }
/* 全站复选框 / 单选框统一品牌色（覆盖浏览器默认蓝色） */
input[type="checkbox"], input[type="radio"] { accent-color: var(--cas-accent); }
a { color: inherit; text-decoration: none; }
table { border-collapse: collapse; }
img, svg, video { display: block; max-width: 100%; }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--cas-accent); outline-offset: 2px; border-radius: 4px; }

/* 滚动条（webkit） */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--cas-border-mid);
  border-radius: 5px;
  border: 2px solid var(--cas-bg-base);
}
::-webkit-scrollbar-thumb:hover { background: var(--cas-border-hover); }


/* =============================================================================
 *  1. DESIGN TOKENS · 亮色主题（默认）
 * ============================================================================= */
:root {
  /* --- Color · 中性 --- */
  --cas-bg-base:        #f7f7f5;
  --cas-bg-white:       #ffffff;
  --cas-bg-tag:         #f0f0ec;
  /* L3 嵌套子表底色：比 bg-base 更浅，靠近 white，用于 3 层嵌套时区分 L2/L3 */
  --cas-bg-sub-l3:      #fbfbf9;
  --cas-bg-sidebar:     #181a1e;
  --cas-bg-sidebar-hover:#23272e;

  --cas-border:         rgba(0,0,0,0.07);
  --cas-border-mid:     rgba(0,0,0,0.10);
  --cas-border-hover:   rgba(0,0,0,0.16);

  --cas-text-primary:   #1a1a1a;
  --cas-text-secondary: #6b6b6b;
  --cas-text-muted:     #a0a0a0;
  --cas-text-sidebar:   #767b8c;
  --cas-text-on-accent: #ffffff;

  /* --- Color · 品牌主色（C · 提亮降饱 #E8A140 HSL 33°, 76%, 58%） --- */
  --cas-accent:         #E8A140;
  --cas-accent-rgb:     232,161,64;
  --cas-accent-hover:   #B5801C;
  --cas-accent-soft:    rgba(232,161,64,0.08);

  /* hover 高亮统一用品牌色软底，与 access/role-item / perm-row 等保持一致 */
  --cas-hover-bg:       var(--cas-accent-soft);

  /* --- Color · 危险/成功/信息（非状态色，组件级使用） --- */
  --cas-danger:         #d94f4f;
  --cas-danger-soft:    rgba(217,79,79,0.08);
  --cas-success:        #3a9b5c;
  --cas-success-soft:   rgba(58,155,92,0.10);
  --cas-info:           #5a78c8;
  --cas-warning:        #B5801C;

  /* --- Layout --- */
  --cas-sidebar-w:      56px;
  --cas-topbar-h:       52px;

  /* --- Radius --- */
  --cas-radius-xs:      4px;     /* badge */
  --cas-radius-sm:      6px;     /* button / input / select */
  --cas-radius-md:      8px;     /* nav-item / popover */
  --cas-radius-lg:      10px;    /* table-wrap / tool-card */
  --cas-radius-xl:      12px;    /* modal / project card / general card */
  --cas-radius-full:    9999px;  /* pill / avatar */

  /* --- Shadow --- */
  --cas-shadow-sm:      0 1px 2px rgba(0,0,0,0.04);
  --cas-shadow-md:      0 6px 20px rgba(0,0,0,0.10);
  --cas-shadow-lg:      0 8px 32px rgba(0,0,0,0.12);

  /* --- Easing / duration --- */
  --cas-ease:           cubic-bezier(.4,0,.2,1);
  --cas-dur-fast:       0.15s;
  --cas-dur-base:       0.18s;
  --cas-dur-slow:       0.5s;

  /* --- Font weight (only 400/600 used; 400 = browser default) --- */
  --cas-fw-bold:        600;

  /* --- Card gap · 横向卡片网格的统一间距 ---
     用于 .projects-grid / .info-cards-inner / .prep-grid / .asset-grid 等
     "并排卡片"场景。垂直堆叠的 .cas-card+.cas-card 仍走 margin-top:20px。 */
  --cas-gap-card:       12px;

  /* --- 默认状态色（fallback；运行时由 base-design.js 注入实际值覆盖） --- */
  /* project */
  --cas-status-project-todo:        #3c82dc;
  --cas-status-project-in_progress: #c07a10;
  --cas-status-project-completed:   #3a9b5c;
  --cas-status-project-cancelled:   #888888;
  /* asset */
  --cas-status-asset-todo:          #3c82dc;
  --cas-status-asset-in_progress:   #c07a10;
  --cas-status-asset-completed:     #3a9b5c;
  --cas-status-asset-confirmed:     #7040c8;
  /* task */
  --cas-status-task-todo:           #3c82dc;
  --cas-status-task-in_progress:    #c07a10;
  --cas-status-task-pending_review: #5a78c8;
  --cas-status-task-pending_revision:#c05818;
  --cas-status-task-approved:       #3a9b5c;
  --cas-status-task-cancelled:      #888888;
  /* generation */
  --cas-status-generation-pending:    #907200;
  --cas-status-generation-processing: #c07a10;
  --cas-status-generation-done:       #3a9b5c;
  --cas-status-generation-failed:     #b83232;
  /* review · 变量名与 /system/statuses/ 后台 key 一一对应，方便用户改色直达
     版本审核状态 5 态：未提交 / 待审核 / 全部使用 / 部分使用 / 不使用。
     旧 approved/closed 变量保留作向后兼容（历史模板/数据），新模板用 all_used/partial_used/not_used。 */
  --cas-status-review-pending_review: #907200;
  --cas-status-review-all_used:       #3a9b5c;
  --cas-status-review-partial_used:   #c98a2b;
  --cas-status-review-not_used:       #888888;
  --cas-status-review-not_submitted:  #888888;
  /* 兼容旧 key */
  --cas-status-review-approved:       #3a9b5c;
  --cas-status-review-closed:         #c05818;

  /* badge 浅背景 alpha（亮色主题） */
  --cas-status-bg-alpha: 0.13;
}

/* --- 旧名别名（保留兼容现有 13 页面，禁止新增使用） --- */
:root {
  --bg:               var(--cas-bg-base);
  --bg-white:         var(--cas-bg-white);
  --bg-tag:           var(--cas-bg-tag);
  --bg-sidebar:       var(--cas-bg-sidebar);
  --bg-sidebar-hover: var(--cas-bg-sidebar-hover);
  --border:           var(--cas-border);
  --border-mid:       var(--cas-border-mid);
  --border-hover:     var(--cas-border-hover);
  --text-primary:     var(--cas-text-primary);
  --text-secondary:   var(--cas-text-secondary);
  --text-muted:       var(--cas-text-muted);
  --text-sidebar:     var(--cas-text-sidebar);
  --accent:           var(--cas-accent);
  --accent-light:     var(--cas-accent-soft);
  --sidebar-w:        var(--cas-sidebar-w);
}


/* =============================================================================
 *  2. DESIGN TOKENS · 暗色主题（用 body.theme-dark 启用）
 * ============================================================================= */
body.theme-dark {
  --cas-bg-base:        #21242c;
  --cas-bg-white:       #28292f;     /* 暗色下"白底"用面板色代替 */
  --cas-bg-tag:         #33343b;
  /* L3 嵌套子表底色（暗色）：比 bg-base 稍亮，靠近 white，用于 3 层嵌套 */
  --cas-bg-sub-l3:      #262a32;
  --cas-bg-sidebar:     #181a1e;
  --cas-bg-sidebar-hover:#23272e;

  --cas-border:         rgba(255,255,255,0.06);
  --cas-border-mid:     rgba(255,255,255,0.10);
  --cas-border-hover:   rgba(255,255,255,0.16);

  --cas-text-primary:   #ffffff;
  --cas-text-secondary: #b3b8c5;
  --cas-text-muted:     #7b8299;
  --cas-text-sidebar:   #767b8c;

  --cas-accent-soft:    rgba(232,161,64,0.11);
  --cas-hover-bg:       var(--cas-accent-soft);

  /* 暗色下 badge 浅背景透明度略高，以保证可读 */
  --cas-status-bg-alpha: 0.18;
}


/* §3 TYPOGRAPHY / §4 UTILITY 已下线（v=5）：
   全部 7 个 .cas-text-h{1..6}/body/sm 与 6 个 .cas-text-muted/secondary/ellipsis/flex-* 工具类
   截至 v=5 全站 0 引用；token (--cas-text-muted 等) 仍保留并被各处 var() 消费。
   如未来需要 inline 工具类，按需重新引入。 */


/* =============================================================================
 *  5. LAYOUT · body / sidebar / main / topbar / content
 * ============================================================================= */
.cas-app, body.cas-app {
  display: flex; min-height: 100vh;
  /* 全站筛选栏 sticky actions 默认背景：页面级（无 card 包裹）走页面背景色，
     卡片内的筛选栏由 .cas-card 覆写为白色（见 §13） */
  --cas-filter-right-bg: var(--cas-bg-base);
}

.cas-main, .main {
  margin-left: var(--cas-sidebar-w); flex: 1;
  display: flex; flex-direction: column; min-height: 100vh; min-width: 0;
}

/* 系统管理子页（body.sys-main）锁定 100vh，让内部 #tab-X { overflow-y:auto }
   能正确出垂直滚动条。否则 .cas-main 用 min-height:100vh 无上限，内容多时
   会撑到自然高度，body 的 overflow:hidden 把溢出剪掉但 #tab-X 拿到无穷高
   导致滚动条永远不出现。 */
body.sys-main .cas-main { height: 100vh; min-height: 0; }

.cas-content, .content { flex: 1; padding: 16px 28px 60px; }

/* topbar：高度 52，sticky，无 border-bottom */
.cas-topbar, .topbar {
  height: var(--cas-topbar-h);
  background: var(--cas-bg-base);
  display: flex; align-items: center;
  padding: 0 28px;
  position: sticky; top: 0; z-index: 100;
}
.cas-topbar { justify-content: space-between; }
.cas-topbar-title, .topbar-title {
  font-size: 13px; color: var(--cas-text-secondary); letter-spacing: 0.01em;
  white-space: nowrap; flex-shrink: 0;
}
.cas-topbar-right, .topbar-right { display: flex; align-items: center; gap: 14px; flex-shrink: 0; }


/* =============================================================================
 *  6. SIDEBAR
 * ============================================================================= */
.cas-sidebar, .sidebar {
  width: var(--cas-sidebar-w);
  background: var(--cas-bg-sidebar);
  display: flex; flex-direction: column; align-items: center;
  padding: 11px 0 16px;
  position: fixed; left: 0; top: 0; bottom: 0; z-index: 200;
}
.cas-sidebar-logo, .sidebar-logo {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--cas-accent);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: var(--cas-fw-bold); color: var(--cas-text-on-accent);
  margin-bottom: 20px; cursor: pointer; flex-shrink: 0;
  text-decoration: none;
}
.cas-sidebar-nav, .sidebar-nav {
  display: flex; flex-direction: column; flex: 1;
  align-items: center; width: 100%; gap: 4px;
}
.cas-sidebar-bottom, .sidebar-bottom { display: flex; flex-direction: column; align-items: center; }

.cas-nav-item, .nav-item {
  width: 52px; padding: 6px 2px 5px; border-radius: var(--cas-radius-md);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 3px; cursor: pointer; color: var(--cas-text-sidebar);
  transition: all var(--cas-dur-base); position: relative; text-decoration: none;
}
.cas-nav-item:hover, .nav-item:hover { background: var(--cas-bg-sidebar-hover); color: #dadde4; }
.cas-nav-item.active, .nav-item.active { color: var(--cas-accent); }
.cas-nav-item.active::before, .nav-item.active::before {
  content: ''; position: absolute; left: -2px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 22px; background: var(--cas-accent); border-radius: 0 2px 2px 0;
}
.cas-nav-item svg, .nav-item svg { width: 20px; height: 20px; flex-shrink: 0; }
.cas-nav-label, .nav-label { font-size: 11px; white-space: nowrap; line-height: 1; letter-spacing: 0.01em; }

.cas-nav-icon, .nav-item-icon {
  width: 40px; height: 40px; border-radius: var(--cas-radius-lg);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: var(--cas-text-sidebar); transition: all var(--cas-dur-base);
}
.cas-nav-icon:hover, .nav-item-icon:hover { background: var(--cas-bg-sidebar-hover); color: #dadde4; }
.cas-nav-icon svg, .nav-item-icon svg { width: 20px; height: 20px; }


/* =============================================================================
 *  7. TOPBAR · credits-pill / avatar
 * ============================================================================= */
.cas-credits-pill, .credits-pill {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--cas-text-secondary);
}
.cas-credits-icon, .credits-icon, .credits-dot {
  width: 6px; height: 6px; background: var(--cas-accent); border-radius: 50%;
}
/* 个人+团队积分双 pill 分组（团队 pill 无团队分配时整组隐藏，见 CAS.credits.render） */
.cas-credits-group { display: flex; align-items: center; gap: 10px; }
.cas-credits-label { color: var(--cas-text-muted); }
.cas-credits-divider { width: 1px; height: 14px; background: var(--cas-border-mid); }
.cas-credits-icon-team { background: var(--cas-success); }

.cas-avatar, .avatar {
  width: 30px; height: 30px; border-radius: 50%;
  background: linear-gradient(135deg, var(--cas-accent), var(--cas-accent-hover));
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: var(--cas-fw-bold); color: var(--cas-text-on-accent);
  cursor: pointer; user-select: none;
}

/* ── 工具页 / 详情页返回按钮 + 分隔线（topbar-left 内组合）──
   用法：
     <header class="cas-topbar">
       <div class="topbar-left">
         <a class="cas-topbar-back" href="..." data-tip="返回">←</a>
         <div class="cas-topbar-sep"></div>
         <div class="cas-topbar-title">...</div>
       </div>
       ...
     </header>
   :has(.cas-topbar-back) 选择器自动收紧左 padding 为 12px，credit 右侧仍 28px 与全站对齐 */
.cas-topbar-back {
  width: 28px; height: 28px;
  border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--cas-text-secondary);
  transition: all var(--cas-dur-base);
  text-decoration: none;
  flex-shrink: 0;
}
.cas-topbar-back:hover { background: var(--cas-bg-tag); color: var(--cas-text-primary); }
.cas-topbar-back svg { width: 16px; height: 16px; }
.cas-topbar-sep {
  width: 1px; height: 14px;
  background: var(--cas-border-mid);
  flex-shrink: 0;
}
.cas-topbar:has(.cas-topbar-back) { padding: 0 28px 0 12px; }


/* =============================================================================
 *  8. PAGE HEADER
 * ============================================================================= */
.cas-page-header, .page-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 20px; gap: 10px;
  /* 永不换行，窗口窄时直接截断（不出滚动条） */
  flex-wrap: nowrap; overflow: hidden;
}
.cas-page-title, .page-title {
  font-size: 22px; font-weight: var(--cas-fw-bold); letter-spacing: -0.01em;
  color: var(--cas-text-primary);
  /* 永不换行；窗口窄时直接截断（…），不换行不出滚动条 */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0; flex: 0 1 auto;
}
/* .cas-page-subtitle / .cas-page-actions 已下线（v=5）：0 引用 */


/* =============================================================================
 *  9. TABS · 全站统一下划线型
 * ============================================================================= */
.cas-tabs, .page-tabs, .tabs {
  display: flex; gap: 4px;
  border-bottom: 1px solid var(--cas-border-mid);
  margin-bottom: 20px;
  /* 窗口窄时可横向滚动，但隐藏滚动条（Firefox + Chrome/Safari/Edge） */
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;
  flex-shrink: 0;
}
.cas-tabs::-webkit-scrollbar,
.page-tabs::-webkit-scrollbar,
.tabs::-webkit-scrollbar { display: none; }
.cas-tab, .page-tab, .tab {
  padding: 8px 16px;
  font-family: inherit; font-size: 13px; font-weight: var(--cas-fw-bold);
  color: var(--cas-text-muted); background: transparent; border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer; transition: color var(--cas-dur-base), border-color var(--cas-dur-base);
  margin-bottom: -1px; white-space: nowrap; flex-shrink: 0;
}
.cas-tab:hover, .page-tab:hover, .tab:hover { color: var(--cas-text-primary); }
.cas-tab.active, .page-tab.active, .tab.active {
  color: var(--cas-accent); border-bottom-color: var(--cas-accent);
}


/* =============================================================================
 * 10. BUTTONS · 三档高度 32 / 28 / 24
 * ============================================================================= */
.cas-btn, .btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 32px; padding: 0 14px;
  background: var(--cas-accent); color: var(--cas-text-on-accent); border: none;
  border-radius: var(--cas-radius-sm);
  font-family: inherit; font-size: 13px; font-weight: var(--cas-fw-bold);
  cursor: pointer; transition: opacity var(--cas-dur-base);
  white-space: nowrap; user-select: none;
}
.cas-btn:hover, .btn:hover { opacity: 0.88; }
/* :disabled 统一规则：所有按钮档 opacity 0.4 + not-allowed。
 * .cas-btn-approved / .cas-btn-danger 必须单列 —— 它们各自的非 disabled CSS 把 background
 * / border 写死成强色（lime / 红描边），如果不在这覆盖，浏览器默认只灰文字、底色纹丝不动，
 * 会被误以为按钮还能点（业务方反馈："通过按钮在不能点时跟驳回按钮视觉不一致"）。 */
.cas-btn:disabled, .btn:disabled,
.cas-btn-sm:disabled, .btn-sm:disabled,
.cas-btn-sm-primary:disabled,
.cas-btn-approved:disabled, .btn-approved:disabled,
.cas-btn-danger:disabled, .btn-danger:disabled { opacity: 0.4; cursor: not-allowed; }

/* 全档按钮内的 svg/img 都不允许被 flex 压缩（窄窗下图标依然可见）*/
.cas-btn svg, .cas-btn-ghost svg, .cas-btn-sm svg, .cas-btn-sm-primary svg,
.btn svg, .btn-ghost svg, .btn-sm svg,
.cas-btn img, .cas-btn-ghost img, .cas-btn-sm img, .cas-btn-sm-primary img { flex-shrink: 0; }

.cas-btn-ghost, .btn-ghost {
  display: inline-flex; align-items: center; justify-content: center;
  height: 24px; padding: 0 12px;
  background: transparent; color: var(--cas-text-secondary);
  border: 1px solid var(--cas-border-mid); border-radius: var(--cas-radius-sm);
  font-family: inherit; font-size: 11px; font-weight: var(--cas-fw-bold);
  cursor: pointer; transition: all var(--cas-dur-base);
  white-space: nowrap; user-select: none;
}
.cas-btn-ghost:hover, .btn-ghost:hover {
  border-color: var(--cas-border-hover); color: var(--cas-text-primary);
}

.cas-btn-sm, .btn-sm {
  display: inline-flex; align-items: center; justify-content: center;
  height: 24px; padding: 0 10px;
  background: transparent; color: var(--cas-text-secondary);
  border: 1px solid var(--cas-border-mid); border-radius: var(--cas-radius-sm);
  font-family: inherit; font-size: 11px; font-weight: var(--cas-fw-bold);
  cursor: pointer; transition: all var(--cas-dur-fast);
  white-space: nowrap; user-select: none;
}
.cas-btn-sm:hover, .btn-sm:hover {
  border-color: var(--cas-border-hover); color: var(--cas-text-primary);
}

.cas-btn-sm-primary, .btn-sm-primary {
  height: 24px; padding: 0 10px;
  background: var(--cas-accent); color: var(--cas-text-on-accent); border: none;
  border-radius: var(--cas-radius-sm);
  font-family: inherit; font-size: 11px; font-weight: var(--cas-fw-bold);
  cursor: pointer; transition: opacity var(--cas-dur-fast); white-space: nowrap;
  display: inline-flex; align-items: center; justify-content: center;
}
.cas-btn-sm-primary:hover, .btn-sm-primary:hover { opacity: 0.88; }

/* 审批通过专用：与 cas-btn-sm-primary 同尺寸（24×11px），用黄绿色（#65a30d Lime-600）
 * 与品牌橙同暖调最和谐；颜色比 review-approved badge 更暖（设计取舍：按钮要醒目，badge 用沉稳绿） */
.cas-btn-approved, .btn-approved {
  height: 24px; padding: 0 10px;
  background: #65a30d;
  color: var(--cas-text-on-accent); border: none;
  border-radius: var(--cas-radius-sm);
  font-family: inherit; font-size: 11px; font-weight: var(--cas-fw-bold);
  cursor: pointer; transition: opacity var(--cas-dur-fast); white-space: nowrap;
  display: inline-flex; align-items: center; justify-content: center;
}
.cas-btn-approved:hover, .btn-approved:hover { opacity: 0.88; }

/* 筛选栏按钮统一规范（v5.4）
   筛选栏（cas-filter-bar / cas-filter-outer）内的所有按钮统一走 ghost 视觉：
     · 透明底 + border-mid 边框 + text-secondary 文字 + bold
     · 24px 高 → .cas-btn-ghost（重置 / 字段 / 折叠 / 全部展开等"与字段并排的"辅助操作，padding 12px）
     · 24px 高 → .cas-btn-sm    （表格内 / 与 sm-primary 并排的次级操作，padding 10px）
     · 主 CTA → .cas-btn-sm-primary（24px 品牌橙；创建 / 新建）
   不要在筛选栏使用：白底按钮、自定义 .filter-clear、不带边框的纯文字按钮。 */

/* TablePrefs「字段」按钮 active 态：当存在隐藏列（非全选）时 JS 加 .tp-active class。
   叠加在 .cas-btn-ghost 上 → 品牌橙线框 + 品牌橙文字，提示用户已自定义字段可见性。 */
.cas-btn-ghost.tp-toggle-btn.tp-active,
.cas-btn-ghost.tp-toggle-btn.tp-active:hover {
  border-color: var(--cas-accent);
  color: var(--cas-accent);
}

/* 可点击状态 badge（叠加在 .cas-badge 上）：cursor:pointer + 右侧 ▾ 下拉小箭头，
   提示用户该 badge 可点击切换状态。tasks.html / assets.html 等共用。 */
.cas-badge.badge-clickable {
  cursor: pointer; display: inline-flex; align-items: center; gap: 3px;
}
.cas-badge.badge-clickable::after { content: '▾'; font-size: 11px; opacity: 0.6; }

/* 危险按钮：可叠加在 .cas-btn / .cas-btn-ghost / .cas-btn-sm / .cas-btn-sm-primary 任一档
   显式 1px solid 边框，确保叠加在 sm-primary（border:none）上也能显示边框 */
.cas-btn-danger, .btn-danger {
  color: var(--cas-danger);
  background: transparent;
  border: 1px solid rgba(217,79,79,0.3);
}
.cas-btn-danger:hover, .btn-danger:hover {
  background: var(--cas-danger-soft); border-color: rgba(217,79,79,0.5);
}

/* 成功按钮：与 cas-btn-danger 对仗（绿描边透明底），用于"启用 / 启动 / 激活"等正向操作 */
.cas-btn-success, .btn-success {
  color: var(--cas-success);
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--cas-success) 35%, transparent);
}
.cas-btn-success:hover, .btn-success:hover {
  background: var(--cas-success-soft);
  border-color: color-mix(in srgb, var(--cas-success) 55%, transparent);
}

/* accent 按钮（与 btn 等价；保留旧名 .btn-accent） */
.btn-accent {
  height: 28px; padding: 0 12px;
  background: var(--cas-accent); color: var(--cas-text-on-accent); border: none;
  border-radius: var(--cas-radius-sm);
  font-size: 11px; font-weight: var(--cas-fw-bold);
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; transition: opacity var(--cas-dur-base); white-space: nowrap;
}
.btn-accent:hover { opacity: 0.88; }


/* =============================================================================
 * 11. FORM CONTROLS · 页面级（field 容器内）
 * ============================================================================= */
.cas-field, .field { margin-bottom: 14px; }
.cas-field label, .field label,
.cas-field-label, .field-label {
  display: block; font-size: 13px; font-weight: var(--cas-fw-bold);
  color: var(--cas-text-primary); margin-bottom: 5px;
}
.cas-field-hint  { font-size: 11px; color: var(--cas-text-muted); margin-top: 4px; }
/* .cas-field-error 已下线（v=5）：0 引用，模板用页内 .field-error */

/* ⚠️ 必须排除 [type=checkbox/radio]，否则 width:100%/height:36px/appearance:none
   会把 checkbox 击穿成"长条输入框"。filter-bar 的同款规则也做了排除。 */
.cas-field input:not([type=checkbox]):not([type=radio]),
.cas-field select, .cas-field textarea,
.field input:not([type=checkbox]):not([type=radio]),
.field select, .field textarea {
  width: 100%; height: 36px; padding: 0 10px;
  font-family: inherit; font-size: 13px; color: var(--cas-text-primary);
  background: var(--cas-bg-white); border: 1px solid var(--cas-border-mid);
  border-radius: var(--cas-radius-sm); outline: none;
  transition: border-color var(--cas-dur-base);
  appearance: none;
}
.cas-field textarea, .field textarea {
  height: 72px; padding: 8px 10px; resize: vertical;
}
.cas-field input:not([type=checkbox]):not([type=radio]):focus,
.cas-field select:focus, .cas-field textarea:focus,
.field input:not([type=checkbox]):not([type=radio]):focus,
.field select:focus, .field textarea:focus {
  border-color: var(--cas-accent);
}
.cas-field input:not([type=checkbox]):not([type=radio]):disabled,
.cas-field select:disabled, .cas-field textarea:disabled,
.field input:not([type=checkbox]):not([type=radio]):disabled,
.field select:disabled, .field textarea:disabled {
  background: var(--cas-bg-tag); color: var(--cas-text-muted); cursor: not-allowed;
  opacity: 1;  /* 覆盖浏览器对 select:disabled 的默认 ~0.7 半透明 */
}


/* =============================================================================
 * 12. FILTER BAR
 * ============================================================================= */
.cas-filter-bar, .filter-bar {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: nowrap;
  /* 不独立滚动；横向滚动由父级 .cas-filter-outer 整体接管 */
}
.cas-filter-bar > *, .filter-bar > * { flex-shrink: 0; }

.cas-filter-bar input:not([type=checkbox]):not([type=radio]),
.cas-filter-bar select,
.filter-bar input:not([type=checkbox]):not([type=radio]),
.filter-bar select {
  height: 28px; padding: 0 8px;
  border: 1px solid var(--cas-border-mid); border-radius: var(--cas-radius-sm);
  font-family: inherit; font-size: 11px;
  color: var(--cas-text-primary); background: var(--cas-bg-white);
  outline: none; transition: border-color var(--cas-dur-base);
}
.cas-filter-bar input:focus, .cas-filter-bar select:focus,
.filter-bar input:focus, .filter-bar select:focus { border-color: var(--cas-accent); }
/* 筛选栏窄列限宽 modifier：选项很长时给单个 select 加 .cas-filter-narrow 类，
   避免被长 option 撑爆 filter-bar 宽度。配合 base 默认行为使用 */
.cas-filter-bar select.cas-filter-narrow,
.filter-bar select.cas-filter-narrow { max-width: 100px; }
/* 筛选栏 checkbox/radio 还原原生 13×13，并归零 UA 默认 margin(3px 上下)
   —— 否则 base 上面那条 height:28px 误中 [type=checkbox/radio]，
   叠加默认 margin 让 flex 父级取最大 outer-size 34px，把整个 filter-bar
   高度从 28 拉到 34（如「查看所有成员任务」复选框场景）。*/
.cas-filter-bar input[type=checkbox], .cas-filter-bar input[type=radio],
.filter-bar input[type=checkbox], .filter-bar input[type=radio] {
  width: 13px; height: 13px; margin: 0; cursor: pointer;
}

/* 筛选栏右对齐组：从「查看所有成员」「批量导入」「+ 创建」等右侧操作开始，
   一律用 <div class="cas-filter-right"> 包起来，自动靠右排成一组。
   - flex 父级：margin-left:auto 吃掉左侧剩余空间
   - grid 父级（如 assets 10 列对齐）：页面再补 grid-column 落位即可，不会冲突
   - 窄窗：白名单不参与换行/收缩，让外层 cas-filter-outer 的 overflow-x:auto 接管横滚
   - 内容溢出时（如 profile 11 个 filter）：position:sticky right:0 让 actions 始终贴
     cas-filter-outer 右边可见，filters 从下方滚过去；white 背景遮住下方滚动内容，
     左缘 ::before 渐变（透明→白）告诉用户"左侧有更多内容可滚" */
.cas-filter-bar > .cas-filter-right,
.filter-bar > .cas-filter-right,
.cas-filter-bar > .filter-right,
.filter-bar > .filter-right {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  flex-wrap: nowrap;
  justify-content: flex-end;
  white-space: nowrap;
  min-width: max-content;
  position: sticky;
  right: 0;
  background: var(--cas-filter-right-bg, var(--cas-bg-white));
  padding-left: 12px;
  z-index: 1;
}
.cas-filter-bar > .cas-filter-right::before,
.filter-bar > .cas-filter-right::before,
.cas-filter-bar > .filter-right::before,
.filter-bar > .filter-right::before {
  content: '';
  position: absolute;
  left: -24px;
  top: 0;
  bottom: 0;
  width: 24px;
  background: linear-gradient(to right, transparent, var(--cas-filter-right-bg, var(--cas-bg-white)));
  pointer-events: none;
}
/* ::after：向上延伸覆盖多行筛选栏（如 assets）所有行的右侧区域。
   单行场景：::after 从 sticky 顶上去 100vh，但 cas-filter-outer overflow-y:hidden 会把它
   裁到 row 高度（即上方无可见内容，::after 被裁成 0），无副作用。
   多行场景：::after 延伸覆盖上方所有 row 的右侧，与 sticky 形成完整的右侧"盖子"，
   同样保持左缘 24px 渐变与 sticky 本体的 ::before 视觉对齐。 */
.cas-filter-bar > .cas-filter-right::after,
.filter-bar > .cas-filter-right::after,
.cas-filter-bar > .filter-right::after,
.filter-bar > .filter-right::after {
  content: '';
  position: absolute;
  bottom: 100%;
  left: -24px;
  right: 0;
  height: 100vh;
  background: linear-gradient(
    to right,
    transparent 0,
    var(--cas-filter-right-bg, var(--cas-bg-white)) 24px
  );
  pointer-events: none;
}
/* 右对齐组内每个直系子元素也禁止收缩 / 自身换行 */
.cas-filter-bar > .cas-filter-right > *,
.filter-bar > .cas-filter-right > *,
.cas-filter-bar > .filter-right > *,
.filter-bar > .filter-right > * {
  flex-shrink: 0;
  white-space: nowrap;
}

/* ── filter-outer: 全站统一筛选栏外壳（单行/多行通用） ──
 *  · 上 padding 0、下 padding 10（与表格/卡片间距 10）
 *  · 子 .cas-filter-bar flex column + 行间 5px；align-items flex-start 让子保持自然宽度
 *  · 整体横向滚动接管（多行同步滚），隐藏滚动条
 *  · cas-tabs 紧跟 outer 时上移 10 → 净 tab→filter 间距 = 10
 *  · 在 tab-content 内时由 tab-content 自己 margin-top:-10 解决（避免被 overflow:hidden 裁剪）
 */
.cas-filter-outer {
  padding: 0 0 10px 0;
  flex-shrink: 0;
  display: flex; flex-direction: column; gap: 5px;
  align-items: flex-start;        /* 子不 stretch，filter-bar 自然宽度 → outer 整体可横滚 */
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none;          /* Firefox 隐藏滚动条 */
}
.cas-filter-outer::-webkit-scrollbar { display: none; }   /* Chrome/Safari/Edge 隐藏滚动条 */
/* align-items:flex-start 让子行不拉伸；width:100% 补回全宽，使 1fr / margin-left:auto 正常右对齐 */
.cas-filter-outer > .cas-filter-bar,
.cas-filter-outer > .filter-bar { width: 100%; }

/* tabs 与 outer 是相邻兄弟（无 tab-content 包裹场景） */
.cas-tabs + .cas-filter-outer,
.page-tabs + .cas-filter-outer,
.tabs + .cas-filter-outer { margin-top: -10px; }

/* Wrapper 场景 fallback（v=27）：当 .cas-tabs 被装在容器（如 system 管理后台的
   #sys-sticky-top）里，而 .cas-filter-outer 又在相邻 sibling 容器（#tab-{slug}）
   的首位时，上面的相邻兄弟选择器够不着，需要把后者整体上移 10px。
   ⚠️ -10 必须加在 wrapper（如 #tab-{slug}）本身，不能加在 .cas-filter-outer 上：
   wrapper 通常带 overflow-y:auto（列表页高度锁定 pattern），加在子元素上会被裁剪
   掉负 margin 区域 → 筛选栏顶部一半被吃掉（base v=26 已踩过）。
   :has(> .cas-tabs) 锁定"直接包 .cas-tabs"的 wrapper；+ *:has(> .cas-filter-outer:first-child)
   锁定相邻 sibling 且其首位是 .cas-filter-outer 的目标 wrapper。 */
:has(> .cas-tabs)  + *:has(> .cas-filter-outer:first-child),
:has(> .page-tabs) + *:has(> .cas-filter-outer:first-child),
:has(> .tabs)      + *:has(> .cas-filter-outer:first-child) { margin-top: -10px; }


/* =============================================================================
 * 13. CARD / PANEL
 *  · 单卡 padding 24，圆角 12 (--cas-radius-xl)
 *  · 垂直堆叠卡片：相邻 margin-top 20
 *  · 横向并排卡片网格：用 var(--cas-gap-card) (= 12px)
 *    适用场景：projects-grid / info-cards-inner / prep-grid / asset-grid
 * ============================================================================= */
.cas-card, .card, .panel {
  background: var(--cas-bg-white);
  border: 1px solid var(--cas-border-mid);
  border-radius: var(--cas-radius-xl);
  padding: 24px;
  /* 卡片内的筛选栏 sticky actions 用白底融合卡片背景；页面级（无 card 包裹）的筛选栏
     由 .cas-app 默认值 --cas-filter-right-bg: var(--cas-bg-base) 接管 */
  --cas-filter-right-bg: var(--cas-bg-white);
}
.cas-card + .cas-card, .card + .card, .panel + .panel { margin-top: 20px; }
/* 横向并排容器内的相邻卡片不加垂直间距 —— v5.1 这些容器已用 gap 控制，
   .cas-card + .cas-card 的默认 margin-top: 20px 会让第二张卡顶部下移 20px 错位。 */
.cards-row > .cas-card + .cas-card,
.projects-grid > .cas-card + .cas-card,
.info-cards-inner > .cas-card + .cas-card,
.prep-grid > .cas-card + .cas-card,
.asset-grid > .cas-card + .cas-card,
.section-row > .cas-card + .cas-card,
.status-def-layout > .cas-card + .cas-card,
.access-layout > .cas-card + .cas-card {
  margin-top: 0;
}
.cas-card-title, .card-title, .panel-title {
  font-size: 16px; font-weight: var(--cas-fw-bold); color: var(--cas-text-primary);
  margin-bottom: 18px;
  flex-shrink: 0;
  white-space: nowrap;
}
/* 卡片/面板标题栏：紧凑 40px / 13px / 第二+ 子元素整组靠右
   .panel-header 跟 .cas-card-header--bar 共享同一套样式，唯一差异是底色：
     · .panel-header         → 白底（透明继承父 .cas-card），用作"与卡片融合"的标题栏
     · .cas-card-header--bar → 灰底（var(--cas-bg-tag)），用作"明显视觉分层"的紧凑信息卡顶部
   布局：第一个子元素靠左 + 第二个子元素 margin-left:auto 把后续整组推到最右，组内 10px gap。 */
.panel-header,
.cas-card-header--bar {
  display: flex; align-items: center; gap: 10px;
  padding: 0 14px; height: 40px;
  border-bottom: 1px solid var(--cas-border);
  font-size: 13px; font-weight: 600;
  color: var(--cas-text-primary);
  flex-shrink: 0;
  /* 窗口收窄时不允许内容换行（panel-header 是固定 40px 高，换行会被裁/溢出）
     窄到放不下时由父 .cas-card 的 overflow:hidden 接管裁剪。 */
  white-space: nowrap;
}
.panel-header > :first-child + *,
.cas-card-header--bar > :first-child + * { margin-left: auto; }
/* panel-header 内的 title 强制 13px / 0 margin（独立用还是 16px）
   覆盖 .panel-title（旧名）+ .cas-card-title（cas-* 现代名）+ .card-title（旧别名），
   保持 13px 缩小规则对三套同义类名一致生效。 */
.panel-header .panel-title,
.panel-header .cas-card-title,
.panel-header .card-title { font-size: 13px; margin-bottom: 0; }

/* 灰底变体：唯一差异是底色 */
.cas-card-header--bar { background: var(--cas-bg-tag); }


/* =============================================================================
 * 14. TABLES · 行高 36 / 居中对齐 / .td-left 例外
 * ============================================================================= */
.cas-table-wrap, .table-wrap {
  overflow-x: auto;
  border: 1px solid var(--cas-border);
  border-radius: var(--cas-radius-lg);
  background: var(--cas-bg-white);
}

.cas-data-table, .data-table {
  width: 100%; border-collapse: collapse;
}
.cas-data-table th, .data-table th {
  font-size: 11px; font-weight: var(--cas-fw-bold);
  color: var(--cas-text-primary);
  text-align: center;
  padding: 9px 8px; line-height: 17px;
  background: var(--cas-bg-tag);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  box-sizing: border-box;
  border-bottom: 1px solid var(--cas-border-mid);
}
.cas-data-table td, .data-table td {
  font-size: 11px; line-height: 17px;
  color: var(--cas-text-secondary);
  text-align: center;
  padding: 9px 8px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  box-sizing: border-box;
  border-bottom: 1px solid var(--cas-border);
  vertical-align: middle;
}
.cas-data-table tr:last-child td,
.data-table tr:last-child td { border-bottom: none; }
/* hover：用 :not(:has(tr:hover)) 限定"自身是最深的被 hover tr"——避免在嵌套表格中
   父 tr 与子 tr 同时高亮。`> td` 直接子选择器再保险一层：父 tr 即使被 hover
   也不会把 hover 背景跨表渗到嵌套子表的 td。 */
.cas-data-table tr:hover:not(:has(tr:hover)) > td,
.data-table tr:hover:not(:has(tr:hover)) > td { background: var(--cas-hover-bg); }
.cas-data-table td.td-left, .data-table td.td-left { text-align: left; }

/* 排序表头：在 th 上加 .sortable，并在内部插 <span class="cas-sort-icon"></span>。
   JS 切换 th 的 .sort-asc / .sort-desc 即可让箭头变向 + 染品牌色。
   无排序态显示 ⇅（muted），升序 ↑ / 降序 ↓（accent）。 */
.cas-data-table th.sortable, .data-table th.sortable {
  cursor: pointer; user-select: none; white-space: nowrap;
  transition: color var(--cas-dur-fast);
}
.cas-data-table th.sortable:hover, .data-table th.sortable:hover {
  color: var(--cas-text-secondary);
}
.cas-sort-icon {
  display: inline-block; margin-left: 4px;
  font-size: 11px; opacity: 0.4; line-height: 1;
  transition: opacity var(--cas-dur-fast), color var(--cas-dur-fast);
}
.cas-sort-icon::before { content: "⇅"; }
.cas-data-table th.sort-asc  .cas-sort-icon,
.cas-data-table th.sort-desc .cas-sort-icon,
.data-table th.sort-asc  .cas-sort-icon,
.data-table th.sort-desc .cas-sort-icon {
  opacity: 1; color: var(--cas-accent);
}
.cas-data-table th.sort-asc  .cas-sort-icon::before,
.data-table     th.sort-asc  .cas-sort-icon::before { content: "↑"; }
.cas-data-table th.sort-desc .cas-sort-icon::before,
.data-table     th.sort-desc .cas-sort-icon::before { content: "↓"; }


/* =============================================================================
 * 15. BADGE · 状态标签
 *  ★ 颜色完全由 CSS 变量 --cas-status-{entity}-{key} 驱动
 *  ★ 用法：<span class="cas-badge" data-entity="task" data-status="todo">待开始</span>
 *  ★ 选用一个用户在 system 设置的"主色"，自动派生 bg/fg：
 *     fg = var(--cas-status-{entity}-{key})  · 文字色 = 用户选的实色
 *     bg = hsl(from var(--cas-status-{entity}-{key}) h s 93%)
 *          保持原色 hue+saturation，亮度提到 93% 得到一个保色相的鲜亮浅底
 *          （= statuses.html _hexToTintBg JS 函数的 CSS 化版本，让 admin 编辑预览
 *          和实际渲染口径完全一致；老的 color-mix(in oklab, .. 13%, transparent)
 *          对低亮度高饱和色（如 #907200 olive yellow）会变脏黄/灰，已弃用）
 *  ★ 兼容老类名（.badge / .status-* / .rs-* / .rv-*）—— base-design.js 会做映射
 * ============================================================================= */
.cas-badge, .badge,
.cas-badge-on, .cas-badge-off, .badge-on, .badge-off {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 2px 7px; border-radius: var(--cas-radius-xs);
  font-size: 11px; font-weight: var(--cas-fw-bold);
  white-space: nowrap; line-height: 1.4;
  /* 默认中性灰，避免没设 data-* 时露白；.cas-badge-on/off 由下方规则覆盖颜色 */
  color: var(--cas-text-muted);
  background: var(--cas-bg-tag);
}

/* 多个 badge 横向排列容器：badge 之间 6px 间距，超出自动换行
   用法：<span class="cas-badge-row">${badge1}${badge2}…</span>
   适用：审核链节点、标签组、多状态指示等。 */
.cas-badge-row {
  display: inline-flex; flex-wrap: wrap;
  gap: 6px; align-items: center; justify-content: center;
  vertical-align: middle;
}

/* 统一规则：根据 data-entity + data-status 拉对应变量。
   每个状态写一条规则（共 22 条）。新增状态时同时改 :root 默认值与本块。 */
.cas-badge[data-entity="project"][data-status="todo"]        { color: var(--cas-status-project-todo);        background: hsl(from var(--cas-status-project-todo) h s 93%); }
.cas-badge[data-entity="project"][data-status="in_progress"] { color: var(--cas-status-project-in_progress); background: hsl(from var(--cas-status-project-in_progress) h s 93%); }
.cas-badge[data-entity="project"][data-status="completed"]   { color: var(--cas-status-project-completed);   background: hsl(from var(--cas-status-project-completed) h s 93%); }
.cas-badge[data-entity="project"][data-status="cancelled"]   { color: var(--cas-status-project-cancelled);   background: hsl(from var(--cas-status-project-cancelled) h s 93%); }

.cas-badge[data-entity="asset"][data-status="todo"]        { color: var(--cas-status-asset-todo);        background: hsl(from var(--cas-status-asset-todo) h s 93%); }
.cas-badge[data-entity="asset"][data-status="in_progress"] { color: var(--cas-status-asset-in_progress); background: hsl(from var(--cas-status-asset-in_progress) h s 93%); }
.cas-badge[data-entity="asset"][data-status="completed"]   { color: var(--cas-status-asset-completed);   background: hsl(from var(--cas-status-asset-completed) h s 93%); }
.cas-badge[data-entity="asset"][data-status="confirmed"]   { color: var(--cas-status-asset-confirmed);   background: hsl(from var(--cas-status-asset-confirmed) h s 93%); }

.cas-badge[data-entity="task"][data-status="todo"]              { color: var(--cas-status-task-todo);              background: hsl(from var(--cas-status-task-todo) h s 93%); }
.cas-badge[data-entity="task"][data-status="in_progress"]       { color: var(--cas-status-task-in_progress);       background: hsl(from var(--cas-status-task-in_progress) h s 93%); }
.cas-badge[data-entity="task"][data-status="pending_review"]    { color: var(--cas-status-task-pending_review);    background: hsl(from var(--cas-status-task-pending_review) h s 93%); }
.cas-badge[data-entity="task"][data-status="pending_revision"]  { color: var(--cas-status-task-pending_revision);  background: hsl(from var(--cas-status-task-pending_revision) h s 93%); }
.cas-badge[data-entity="task"][data-status="approved"]          { color: var(--cas-status-task-approved);          background: hsl(from var(--cas-status-task-approved) h s 93%); }
.cas-badge[data-entity="task"][data-status="cancelled"]         { color: var(--cas-status-task-cancelled);         background: hsl(from var(--cas-status-task-cancelled) h s 93%); }

.cas-badge[data-entity="generation"][data-status="pending"]    { color: var(--cas-status-generation-pending);    background: hsl(from var(--cas-status-generation-pending) h s 93%); }
.cas-badge[data-entity="generation"][data-status="processing"] { color: var(--cas-status-generation-processing); background: hsl(from var(--cas-status-generation-processing) h s 93%); }
.cas-badge[data-entity="generation"][data-status="done"]       { color: var(--cas-status-generation-done);       background: hsl(from var(--cas-status-generation-done) h s 93%); }
.cas-badge[data-entity="generation"][data-status="failed"]     { color: var(--cas-status-generation-failed);     background: hsl(from var(--cas-status-generation-failed) h s 93%); }

/* review · 5 态：未提交/待审核/全部使用/部分使用/不使用；兼容旧 pending/approved/closed/rejected */
.cas-badge[data-entity="review"][data-status="pending"],
.cas-badge[data-entity="review"][data-status="pending_review"] { color: var(--cas-status-review-pending_review); background: hsl(from var(--cas-status-review-pending_review) h s 93%); }
.cas-badge[data-entity="review"][data-status="all_used"],
.cas-badge[data-entity="review"][data-status="approved"]       { color: var(--cas-status-review-all_used);       background: hsl(from var(--cas-status-review-all_used) h s 93%); }
.cas-badge[data-entity="review"][data-status="partial_used"]   { color: var(--cas-status-review-partial_used);   background: hsl(from var(--cas-status-review-partial_used) h s 93%); }
.cas-badge[data-entity="review"][data-status="not_used"]       { color: var(--cas-status-review-not_used);       background: hsl(from var(--cas-status-review-not_used) h s 93%); }
.cas-badge[data-entity="review"][data-status="rejected"],
.cas-badge[data-entity="review"][data-status="closed"]         { color: var(--cas-status-review-closed);         background: hsl(from var(--cas-status-review-closed) h s 93%); }
.cas-badge[data-entity="review"][data-status="not_submitted"]  { color: var(--cas-status-review-not_submitted);  background: hsl(from var(--cas-status-review-not_submitted) h s 93%); }

/* project entity 扩展：项目类型维度（个人 / 团队），非状态色，与 project status 共存 */
.cas-badge[data-entity="project"][data-status="personal"] {
  color: var(--cas-text-secondary);
  background: var(--cas-bg-tag);
}
.cas-badge[data-entity="project"][data-status="team"] {
  color: var(--cas-accent);
  background: color-mix(in oklab, var(--cas-accent) calc(var(--cas-status-bg-alpha) * 100%), transparent);
}

/* media entity（任务媒体类型 / 资产类型）—— 7 档共用中性灰，data-status 留作语义占位
 * 后续若要按 image/video/text/audio/3d/other 分色，仅需改本块（无需改模板）*/
.cas-badge[data-entity="media"][data-status="image"],
.cas-badge[data-entity="media"][data-status="video"],
.cas-badge[data-entity="media"][data-status="text"],
.cas-badge[data-entity="media"][data-status="audio"],
.cas-badge[data-entity="media"][data-status="editing"],
.cas-badge[data-entity="media"][data-status="3d"],
.cas-badge[data-entity="media"][data-status="other"] {
  color: var(--cas-text-secondary);
  background: var(--cas-bg-tag);
}

/* tool entity（工具状态）—— new / soon / maintenance / advance 四档 */
.cas-badge[data-entity="tool"][data-status="new"] {
  color: var(--cas-text-on-accent);
  background: var(--cas-accent);
}
.cas-badge[data-entity="tool"][data-status="soon"] {
  color: var(--cas-info);
  background: color-mix(in oklab, var(--cas-info) calc(var(--cas-status-bg-alpha) * 100%), transparent);
}
.cas-badge[data-entity="tool"][data-status="maintenance"] {
  color: var(--cas-warning);
  background: color-mix(in oklab, var(--cas-warning) calc(var(--cas-status-bg-alpha) * 100%), transparent);
}
.cas-badge[data-entity="tool"][data-status="advance"] {
  color: var(--cas-accent);
  background: color-mix(in oklab, var(--cas-accent) calc(var(--cas-status-bg-alpha) * 100%), transparent);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* 启用/停用：与状态实体无关，直接用语义色 */
.cas-badge-on,  .badge-on  { color: var(--cas-success); background: var(--cas-success-soft); }
.cas-badge-off, .badge-off { color: var(--cas-danger);  background: var(--cas-danger-soft); }


/* =============================================================================
 * 16. MODAL · 三段式（header / body / footer），标题与底部冻结
 * ============================================================================= */
.cas-modal-overlay, .modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.35);
  display: none; align-items: center; justify-content: center;
  z-index: 500;
}
.cas-modal-overlay.open, .modal-overlay.open { display: flex; }

.cas-modal, .modal {
  background: var(--cas-bg-white); border-radius: var(--cas-radius-xl);
  width: 420px; max-width: calc(100vw - 32px); max-height: 90vh;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: var(--cas-shadow-lg);
}
.cas-modal-header, .modal-header {
  padding: 18px 20px 14px; border-bottom: 1px solid var(--cas-border);
  display: flex; align-items: center; justify-content: space-between;
  flex-shrink: 0;
}
.cas-modal-title, .modal-title {
  font-size: 16px; font-weight: var(--cas-fw-bold); color: var(--cas-text-primary);
}
.cas-modal-close {
  width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--cas-radius-sm); color: var(--cas-text-muted); cursor: pointer;
  transition: all var(--cas-dur-base);
}
.cas-modal-close:hover { background: var(--cas-hover-bg); color: var(--cas-text-primary); }

.cas-modal-body, .modal-body {
  padding: 20px; overflow-y: auto; flex: 1;
}
.cas-modal-footer, .modal-footer {
  padding: 18px 20px; border-top: 1px solid var(--cas-border);
  display: flex; justify-content: flex-end; gap: 8px;
  flex-shrink: 0;
}
/* 弹窗内所有按钮统一 32px，与 input/select 同高（footer + body 同款）。
   表格内按钮在下方单独覆盖回 24px 紧凑档（避免把行高撑爆）。 */
.cas-modal-overlay button.cas-btn,       .cas-modal-overlay button.btn,
.cas-modal-overlay button.cas-btn-sm,    .cas-modal-overlay button.btn-sm,
.cas-modal-overlay button.cas-btn-sm-primary, .cas-modal-overlay button.btn-sm-primary,
.cas-modal-overlay button.cas-btn-ghost, .cas-modal-overlay button.btn-ghost {
  height: 32px; padding: 0 14px;
  font-size: 11px; font-weight: var(--cas-fw-bold);
}
/* 表格内的按钮保持 24px 紧凑（与 cas-data-table 内 cas-select-trigger 同档），
   避免 td 行高被撑高。优先级 0,3,1（同上面规则 0,2,1）必赢。 */
.cas-modal-overlay .cas-data-table button.cas-btn-sm,
.cas-modal-overlay .cas-data-table button.cas-btn-sm-primary,
.cas-modal-overlay .cas-data-table button.cas-btn-ghost,
.cas-modal-overlay .data-table button.cas-btn-sm,
.cas-modal-overlay .data-table button.cas-btn-sm-primary,
.cas-modal-overlay .data-table button.cas-btn-ghost {
  height: 24px; padding: 0 10px;
}

/* modal 内输入框 / 下拉框统一 32px 高 / 13px 字号；
   含升级后的 cas-select-trigger（默认 28px/11px 仅用于筛选栏紧凑布局，
   弹窗内表单语境需与 input 对齐到 32px/13px）。
   兼容三种 modal 类层级：.cas-modal-body（base 三段式）/ .modal-body（旧别名）
   / .modal（裸 modal 类，无 -body 内层；如项目设置 / 任务编辑等历史 modal） */
/* 用 .cas-modal-overlay 作锚点 —— 所有 modal 必包在这层；不依赖具体内层
   modal 容器 class（历史遗留有 .cas-modal-body / .modal-body / .modal /
   .settings-modal-inner / .um-modal / .pm-modal 等多套自家命名） */
/* ⚠️ input 必须带 :not([type=checkbox]):not([type=radio])，与上方页面级规则
   对齐特异性（3 class + 1 元素），否则页面级 36px 会赢覆盖弹窗 32px。
   font-size 11px 跟下方 .cas-field .cas-select-trigger（line 1289）同档，
   让弹窗内 input / select / textarea / cas-select trigger 统一 11px —— 否则
   .cas-field input 默认 13px 跟 trigger 11px 视觉对不齐（原 1105 那条 13px 试图
   把 trigger 提到 13px 反方向统一，但被 .cas-field 同特异性后写规则覆盖，纯属无效）。
   textarea 单独成段：只继承字号统一，高度沿用 base line 631-633 的 72px + resize:vertical。 */
.cas-modal-overlay .cas-field input:not([type=checkbox]):not([type=radio]),
.cas-modal-overlay .cas-field select,
.cas-modal-overlay .field input:not([type=checkbox]):not([type=radio]),
.cas-modal-overlay .field select {
  height: 32px;
  font-size: 11px;
}
.cas-modal-overlay .cas-field textarea,
.cas-modal-overlay .field textarea {
  font-size: 11px;
}
.cas-modal-overlay .cas-select-trigger {
  height: 32px;
  font-size: 11px;
  padding: 0 10px;
}
/* 表格单元格内的下拉跟随 td 的 11px 字号（table cells 一律 11px，base §13）；
   高度同步缩到 24px 与 cas-btn-sm 同档，避免 32px 把 td 行高撑到 51px */
.cas-modal-overlay .cas-data-table .cas-select-trigger,
.cas-modal-overlay .data-table .cas-select-trigger {
  font-size: 11px;
  height: 24px;
  padding: 0 8px;
}

/* 紧凑确认弹窗（删除/移出/转换等单段消息+两按钮场景）
   直接挂在 .cas-modal-overlay 内，替代 .cas-modal 三段结构 */
.cas-confirm-modal {
  background: var(--cas-bg-white); border-radius: var(--cas-radius-xl);
  width: 420px; max-width: calc(100vw - 32px);
  padding: 24px 28px 20px;
  box-shadow: var(--cas-shadow-lg);
}
.cas-confirm-title {
  font-size: 16px; font-weight: var(--cas-fw-bold); color: var(--cas-text-primary);
  margin-bottom: 12px;
}
.cas-confirm-body {
  font-size: 13px; color: var(--cas-text-secondary); line-height: 1.7;
  margin-bottom: 8px;
}
/* 确认弹窗主消息内的实体名一律包 <strong>：自动加粗 + 主文字色高亮
   注意：danger-note 内的 <strong> 保持原 danger 色，仅加粗（避免红/黑色拼接） */
.cas-confirm-body strong {
  color: var(--cas-text-primary);
  font-weight: var(--cas-fw-bold);
}
.cas-confirm-danger-note strong {
  font-weight: var(--cas-fw-bold);
}
.cas-confirm-danger-note {
  font-size: 11px; color: var(--cas-danger);
  margin-bottom: 18px;
}
.cas-confirm-actions {
  display: flex; gap: 8px; justify-content: flex-end;
}

/* ──────────────────────────────────────────────────────────────────────────
 * 16.4  SETTINGS MODAL · 项目设置 / 创建弹窗共用 (step indicator + 2col grid)
 *   用法：见 _partials/_project_settings_modal.html
 *   - settings-step-indicator → 步骤点容器（顶部 1/2 进度）
 *   - settings-step-dot[.active|.done] → 圆形步骤点
 *   - settings-step-line → 两个步骤点中间的连线
 *   - settings-2col → 弹窗内常用的 2 列网格（field 上下间距 0）
 * 历史：原各页面（index/projects/project-detail/system/api_reference/system/models）
 * 各写一份相同 CSS，2026-05-26 合并到 base。
 * ────────────────────────────────────────────────────────────────────────── */
.settings-step-indicator { display: flex; align-items: center; gap: 0; flex-shrink: 0; }
.settings-step-dot {
  width: 24px; height: 24px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 600;
  background: var(--cas-bg-tag); color: var(--cas-text-muted);
  border: 1.5px solid var(--cas-border-mid); transition: all 0.2s;
}
.settings-step-dot.active { background: var(--cas-accent);      color: #fff;             border-color: var(--cas-accent); }
.settings-step-dot.done   { background: var(--cas-accent-soft); color: var(--cas-accent); border-color: var(--cas-accent); }
.settings-step-line { width: 28px; height: 1.5px; background: var(--cas-border-mid); }
.settings-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; }
.settings-2col .cas-field { margin-bottom: 0; }


/* =============================================================================
 * 16.5  TOGGLE SWITCH · cas-switch
 *   用法：
 *     <label class="cas-switch">
 *       <input type="checkbox" id="my-id">
 *       <span class="cas-switch-track"></span>
 *       <span class="cas-switch-label">启用</span>   ← 可省略
 *     </label>
 *   JS 读值：document.getElementById('my-id').checked（与原生 checkbox 完全一致）
 *   .cas-switch-label 标准文案：「启用」（弹窗 / 表单内的开关标签）
 * ============================================================================= */
.cas-switch,
.field label.cas-switch,
.cas-field label.cas-switch {
  display: inline-flex; align-items: center; gap: 8px;
  cursor: pointer; user-select: none;
  font-weight: 400;
  /* 重置 .field label / .cas-field label 的 margin-bottom:5px，否则 cas-switch
     作为 <label> 元素会比同行其它非 <label> 控件（如 cas-btn-sm <a>）多 5px 下空间，
     导致两者垂直不对齐 */
  margin-bottom: 0;
}
.cas-switch input[type="checkbox"] {
  position: absolute; opacity: 0; width: 0; height: 0; margin: 0;
}
.cas-switch-track {
  position: relative; display: inline-block; flex-shrink: 0;
  width: 32px; height: 18px;
  background: var(--cas-border-mid); border-radius: 9px;
  transition: background var(--cas-dur-base);
}
.cas-switch-track::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 14px; height: 14px; background: #fff;
  border-radius: 50%; box-shadow: 0 1px 2px rgba(0,0,0,.25);
  transition: transform var(--cas-dur-base);
}
.cas-switch input:checked ~ .cas-switch-track { background: var(--cas-accent); }
.cas-switch input:checked ~ .cas-switch-track::after { transform: translateX(14px); }
.cas-switch-label {
  font-size: 13px; color: var(--cas-text-primary);
}


/* =============================================================================
 * 17. POPOVER · 列设置等浮层
 * ============================================================================= */
.cas-popover, .col-popover {
  display: none; position: absolute; right: 0; top: calc(100% + 6px);
  background: var(--cas-bg-white);
  border: 1px solid var(--cas-border-mid);
  border-radius: var(--cas-radius-md);
  box-shadow: var(--cas-shadow-md);
  padding: 10px 14px; min-width: 160px; z-index: 300;
}
.cas-popover.open, .col-popover.open { display: block; }


/* =============================================================================
 * 18. DROPDOWN MENU · 头像/操作菜单
 * ============================================================================= */
.cas-menu {
  display: none; position: absolute; right: 0; top: calc(100% + 6px);
  background: var(--cas-bg-white);
  border: 1px solid var(--cas-border-mid);
  border-radius: var(--cas-radius-md);
  box-shadow: var(--cas-shadow-md);
  padding: 4px; min-width: 160px; z-index: 300;
}
.cas-menu.open { display: block; }
.cas-menu-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: var(--cas-radius-sm);
  font-size: 13px; color: var(--cas-text-primary);
  cursor: pointer; user-select: none;
  transition: background var(--cas-dur-fast);
}
.cas-menu-item:hover { background: var(--cas-hover-bg); }
.cas-menu-item.danger { color: var(--cas-danger); }
.cas-menu-divider {
  height: 1px; background: var(--cas-border); margin: 4px 0;
}


/* =============================================================================
 * 18.5 SELECT-CUSTOM · 自定义下拉（筛选栏右对齐计数）
 *
 *  用法：原 <select class="cas-select" id="..."> 加属性 data-cas-select；
 *        base-design.js 自动升级为带 trigger + popover 的自定义下拉，
 *        原 select 保留在 DOM 内（hidden）继续承载 value / change 事件。
 *
 *  计数 API：CAS.setSelectCount(selOrId, value, count) → 把 count 写到
 *           对应 <option> 的 dataset.count，popover 内右对齐显示。
 *           count 为 0 / null / '' 时不显示数字。
 *
 *  视觉规范：trigger 与原 28px filter-bar input 同高同字号同边框；
 *           popover option 行 flex space-between：label 左、count 右；
 *           count 用 tabular-nums + min-width 让各行数字列对齐。
 * ============================================================================= */
.cas-select-wrap {
  position: relative;
  display: inline-block;
  vertical-align: middle;
}
/* 表单字段（.cas-field / .field / .cas-w-field）内的 cas-select 自动撑满父宽度 ——
   避免 inline-block 被压成内容宽度。filter-bar 横排 select 不在这些容器内，不受影响。 */
.cas-field .cas-select-wrap,
.field .cas-select-wrap,
.cas-w-field .cas-select-wrap {
  display: block;
  width: 100%;
}
/* 表单字段内的 cas-select trigger 统一 32px / 11px（与控件 chip / input / label 11px 统一）。
   filter-bar 保持默认 28px/11px；弹窗内的覆盖在下方 .cas-modal-overlay 规则里。 */
.cas-field .cas-select-trigger,
.field .cas-select-trigger,
.cas-w-field .cas-select-trigger {
  height: 32px;
  font-size: 11px;
  padding: 0 10px;
}
.cas-select-wrap > select.cas-select-native {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  opacity: 0; pointer-events: none; margin: 0; padding: 0;
  border: 0;
}
.cas-select-trigger {
  display: inline-flex; align-items: center; justify-content: space-between;
  gap: 8px; width: 100%;
  height: 28px; padding: 0 8px;
  border: 1px solid var(--cas-border-mid); border-radius: var(--cas-radius-sm);
  background: var(--cas-bg-white); color: var(--cas-text-primary);
  font-family: inherit; font-size: 11px; line-height: 1;
  cursor: pointer; user-select: none;
  outline: none; transition: border-color var(--cas-dur-base);
  white-space: nowrap;
}
.cas-select-trigger:hover { border-color: var(--cas-text-secondary); }
.cas-select-wrap.open > .cas-select-trigger { border-color: var(--cas-accent); }
/* 底层 native <select> 被设 disabled 时，trigger 视觉跟 .cas-field select:disabled
   保持一致（灰底 / 灰字 / not-allowed），否则用户直观以为字段可改 —— upgradeSelect
   把 select 移进 .cas-select-wrap 后 :disabled 状态不会自动传递到 trigger 按钮 */
.cas-select-native:disabled + .cas-select-trigger {
  background: var(--cas-bg-tag);
  color: var(--cas-text-muted);
  cursor: not-allowed;
  pointer-events: none;
}
.cas-select-native:disabled + .cas-select-trigger:hover { border-color: var(--cas-border); }
.cas-select-native:disabled + .cas-select-trigger .cas-select-caret { opacity: 0.4; }
.cas-select-text {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-align: left;
  /* trigger 的 line-height:1 让 line-box 等于字号，加 overflow:hidden 会裁掉 g/p/j
     等下行字母的 descender。这里 override 给 line-height:1.4 留出 ~4px 容差。
     高度由 inline-flex align-items:center 撑住，整体仍居中。 */
  line-height: 1.4;
}
.cas-select-caret {
  flex-shrink: 0;
  width: 6px; height: 6px;
  border-right: 1.5px solid var(--cas-text-muted);
  border-bottom: 1.5px solid var(--cas-text-muted);
  transform: translateY(-1px) rotate(45deg);
  transition: transform var(--cas-dur-base);
}
.cas-select-wrap.open > .cas-select-trigger .cas-select-caret {
  transform: translateY(2px) rotate(-135deg);
}
/* popover 用 position: fixed，避免被外层 .cas-filter-outer 的 overflow:hidden 裁切；
   定位（left/top/min-width）由 base-design.js 在 open() 时读 trigger 矩形并 inline 写入。
   z-index 600 = 高于 cas-modal-overlay(500) 保证弹窗内的 cas-select 能展开，
   低于 toast(9999) 保证 toast 始终顶层。 */
.cas-select-popover {
  display: none; position: fixed; left: 0; top: 0;
  max-height: 320px; overflow-y: auto;
  background: var(--cas-bg-white);
  border: 1px solid var(--cas-border-mid); border-radius: var(--cas-radius-md);
  box-shadow: var(--cas-shadow-md);
  padding: 4px; z-index: 600;
}
.cas-select-popover.open { display: block; }
.cas-select-option {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 6px 10px; border-radius: var(--cas-radius-sm);
  font-size: 11px; color: var(--cas-text-primary);
  cursor: pointer; user-select: none;
  transition: background var(--cas-dur-fast);
}
.cas-select-option:hover,
.cas-select-option.cas-select-option--active { background: var(--cas-hover-bg); }
.cas-select-option.cas-select-option--selected {
  color: var(--cas-accent); font-weight: var(--cas-fw-bold, 600);
}
.cas-select-opt-label {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-align: left;
}
.cas-select-opt-count {
  flex-shrink: 0;
  font-size: 10px; color: var(--cas-text-muted);
  font-variant-numeric: tabular-nums;
  min-width: 20px; text-align: right;
}
.cas-select-option.cas-select-option--selected .cas-select-opt-count { color: var(--cas-accent); }
.cas-select-opt-count:empty { visibility: hidden; }
/* disabled option：保持可见但不可点（带 dataset disabled 时由 JS 加 class） */
.cas-select-option.cas-select-option--disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.cas-select-option.cas-select-option--disabled:hover { background: transparent; }
/* <optgroup label="..."> 渲染成只读分组标题，跟下面的 option 视觉分层 */
.cas-select-optgroup-label {
  padding: 8px 12px 4px;
  font-size: 10px;
  font-weight: 600;
  color: var(--cas-text-muted);
  letter-spacing: 0.04em;
  cursor: default;
  user-select: none;
  background: var(--cas-bg-base);
}
.cas-select-optgroup-label + .cas-select-option { padding-top: 6px; }
/* 副标签：option 主文案后接的浅色辅助文本（如 model display │ api_model_id） */
.cas-select-opt-sub {
  color: var(--cas-text-muted);
  font-family: ui-monospace, monospace;
  font-size: 11px;
  font-weight: 400;
}


/* =============================================================================
 * 19. TOAST · 全站统一：页面底部水平居中，更显眼更大尺寸
 * ============================================================================= */
.cas-toast-host {
  position: fixed; bottom: 32px; left: 50%;
  transform: translateX(-50%); z-index: 9999;
  display: flex; flex-direction: column-reverse; gap: 10px;
  align-items: center;
  pointer-events: none;
}
.cas-toast {
  pointer-events: auto;
  min-width: 280px; max-width: 520px;
  background: var(--cas-bg-white);
  border: 1px solid var(--cas-border-mid);
  border-left: 4px solid var(--cas-accent);
  border-radius: var(--cas-radius-md);
  box-shadow: 0 8px 24px rgba(0,0,0,0.18), 0 2px 6px rgba(0,0,0,0.10);
  padding: 14px 22px;
  font-size: 13px; font-weight: 500;
  color: var(--cas-text-primary);
  animation: casToastIn 0.28s var(--cas-ease) forwards;
}
.cas-toast.cas-toast-success { border-left-color: var(--cas-success); }
.cas-toast.cas-toast-error   { border-left-color: var(--cas-danger); }
.cas-toast.cas-toast-warning { border-left-color: var(--cas-warning); }
.cas-toast.is-leaving { animation: casToastOut 0.22s var(--cas-ease) forwards; }
@keyframes casToastIn  { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes casToastOut { to   { opacity: 0; transform: translateY(12px); } }


/* =============================================================================
 * 20. TOOLTIP · [data-tip="..."]
 * ============================================================================= */
[data-tip] { position: relative; }
[data-tip]::after {
  content: attr(data-tip);
  position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%);
  background: #1a1a1a; color: #fff;
  font-size: 11px; line-height: 1.4; padding: 4px 8px;
  border-radius: var(--cas-radius-xs); white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity var(--cas-dur-base);
  z-index: 1000;
}
[data-tip]:hover::after { opacity: 1; }


/* §21 SKELETON / §22 PAGINATION / §23 EMPTY STATE 已下线（v=5）：0 引用。
   skeleton/spinner 配套 @keyframes casSkel/casSpin 同步移除；
   .cas-empty / .cas-empty-icon/title/desc 未被任何模板采纳，业务页用各自的页内空态 class。
   未来如需再次引入：去 git 历史里恢复，或参考 design-guide-v5 §6.14/§6.15/§6.16。 */


/* =============================================================================
 * 24. DIVIDER
 * ============================================================================= */
.cas-divider     { height: 1px; background: var(--cas-border); margin: 16px 0; }
.cas-divider-v   { width: 1px; height: 16px; background: var(--cas-border-mid); }


/* =============================================================================
 * 25. ANIMATION · 全站统一入场
 * ============================================================================= */
/* 改造（v=82）：原 fadeUp 含 translateY(14px → 0) 入场动画，但跟
 * onboarding spotlight 不兼容——目标元素动画期间的浮点位置让 mask
 * 跟不上，亚像素抗锯齿露白线（多显示器/低 DPR 屏更明显）。
 * 改成纯 fade-in（无 translate），名字保留 fadeUp 不破坏 32 个引用。
 * 工具仓库页本来就不用这类，不受影响。 */
@keyframes fadeUp {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.cas-animate-in, .content {
  opacity: 0;
  animation: fadeUp var(--cas-dur-slow) ease forwards;
}
.cas-animate-delay-1 { animation-delay: 0.1s; }
/* .cas-animate-delay-2 已下线（v=5）：0 引用 */


/* =============================================================================
 * 26. PRINT
 * ============================================================================= */
@media print {
  .cas-sidebar, .sidebar, .cas-topbar, .topbar { display: none !important; }
  .cas-main, .main { margin-left: 0 !important; }
  .cas-content, .content { padding: 0 !important; }
  body { background: #fff !important; }
}


/* =============================================================================
 * 27. BREADCRUMB · 面包屑导航
 * ============================================================================= */
.cas-breadcrumb { display: flex; align-items: baseline; gap: 6px; font-size: 22px; font-weight: 600; margin-bottom: 16px; }
.cas-breadcrumb-sep { font-size: 16px; color: var(--cas-text-muted); font-weight: 400; }
.cas-breadcrumb-current { font-size: 16px; color: var(--cas-text-secondary); font-weight: 400; }


/* =============================================================================
 * 28. META BAR · 信息行（卡片内 label/value 横向并排，详情页 info-card 用）
 *  · .cas-meta-label / .cas-meta-value：通用文本 token（11px / muted vs primary）
 *  · .cas-meta-bar：横向容器（flex 行 + stretch 等高），适合放在卡片内
 *  · .cas-meta-item：单元格（column flex + 居中 + 短分割线 ::after）
 *  · .cas-meta-value--accent：强调色变体（橙色，高亮某个数字用）
 *  · 列宽 / 容器 padding / item padding 等差异由页面 override（不强制）
 * ============================================================================= */
.cas-meta-bar {
  display: flex; flex-wrap: nowrap; align-items: stretch;
}
.cas-meta-item {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  gap: 5px;
  position: relative;
}
.cas-meta-item:not(:last-child)::after {
  content: ''; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: 1px; height: 28px; background: var(--cas-border);
}
.cas-meta-label { font-size: 11px; color: var(--cas-text-muted); flex-shrink: 0; }
.cas-meta-value { font-size: 11px; color: var(--cas-text-primary); flex-shrink: 0; }
.cas-meta-item .cas-meta-label,
.cas-meta-item .cas-meta-value {
  white-space: nowrap; text-align: center;
}
.cas-meta-item .cas-meta-value {
  min-height: 20px; display: flex; align-items: center; justify-content: center;
}
.cas-meta-value--accent { color: var(--cas-accent); }


/* =============================================================================
 * 29. TOGGLE BUTTON · 表格展开/收起按钮
 * ============================================================================= */
.cas-toggle-btn {
  background: none; border: none; cursor: pointer;
  color: var(--cas-text-muted); font-size: 11px;
  padding: 0 4px; transition: transform 0.2s;
}
.cas-toggle-btn.open   { transform: rotate(0deg); }
.cas-toggle-btn.closed { transform: rotate(-90deg); }


/* =============================================================================
 * 30. NESTED TABLE · 嵌套表格色彩规范
 * ============================================================================= */
.cas-sub-wrap-td { padding: 0 !important; background: var(--cas-bg-base) !important; }
.cas-spacer-td   { background: var(--cas-bg-tag); }

/* 3 层嵌套时，L3 包裹 td 使用更浅的 sub-l3 底色，与 L2 的 bg-base 区分。
   用法：在 L3 sub-wrap 的 td 上额外加 .cas-sub-wrap-td--l3 */
.cas-sub-wrap-td.cas-sub-wrap-td--l3 { background: var(--cas-bg-sub-l3) !important; }


/* =============================================================================
 * 31. SCROLLABLE TABLE · 可滚动表格变体（表头冻结）
 *  · sticky 只匹配 wrap 直接子表（child selector），避免嵌套子表 thead 也 sticky
 *    导致主子表头互相覆盖。
 * ============================================================================= */
.cas-table-wrap--scroll { overflow-y: auto; }
.cas-table-wrap--scroll > .cas-data-table > thead th,
.cas-table-wrap--scroll > .data-table > thead th {
  /* z-index 必须高于单元格内定位内容（如视频缩略图播放钮 .cas-video-badge z-index:2），
     否则滚动时 badge 会盖在冻结表头文字上（两者同 z-index 时 tbody 在 DOM 靠后会赢）。 */
  position: sticky; top: 0; z-index: 3;
}


/* =============================================================================
 * 32. TOOL PAGE · 工具页（双栏 gallery + control 布局）通用样式
 *  · body 加 class="cas-tool-page" 启用
 *  · 工具页信息密度高：topbar/credits/avatar/menu 字号下沉 11px（base 默认 13px）
 *  · 字段标签 .cas-tool-field-label：11px / 400 / muted 灰，让选项内容跳出来
 *    （v5 §3 推荐 13/600 字段标签是给"低密度页"，工具页双栏紧凑布局用 11/400/muted）
 *  · 配套容器：.cas-tool-field —— flex column + 8px gap
 * ============================================================================= */
body.cas-tool-page .cas-topbar-title,
body.cas-tool-page .cas-credits-pill,
body.cas-tool-page .cas-avatar,
body.cas-tool-page .cas-menu-item { font-size: 11px; }

.cas-tool-field { display: flex; flex-direction: column; gap: 8px; }
.cas-tool-field-label {
  font-size: 11px;
  color: var(--cas-text-muted);
}


/* =============================================================================
 * 33. TD-LINK · 表格内可点击文本链接（项目名 / 资产名 / 任务名等）
 *  · 继承 td 颜色 + 字重，不加粗，不改变布局
 *  · 常显浅灰下划线，hover 转主色
 * ============================================================================= */
.td-link {
  color: inherit;
  font-weight: inherit;
  text-decoration: underline;
  /* 跟随 currentColor 25% alpha：亮色主题下=深字带淡灰下划线，
     暗色主题下=浅字带淡浅下划线，无需 theme override */
  text-decoration-color: color-mix(in srgb, currentColor 25%, transparent);
  text-underline-offset: 3px;
  transition: color 0.18s, text-decoration-color 0.18s;
}
.td-link:hover {
  color: var(--cas-accent);
  text-decoration-color: var(--cas-accent);
}


/* =============================================================================
 * 34. THUMB · 表格内缩略图（任务 / 资产 / 版本通用，48×36 单一档）
 *  · 配套占位（无图时）：.cas-thumb-empty
 *  · 替代各页面自家定义的 .task-thumb / .asset-thumb / .sub-thumb
 *  · 注：task-detail 提交审核弹窗的 .submit-ver-thumb（60×45）独立保留
 * ============================================================================= */
.cas-thumb {
  width: 48px; height: 36px;
  border-radius: var(--cas-radius-xs);
  object-fit: cover;
  display: block; margin: auto;
}
.cas-thumb-empty {
  width: 48px; height: 36px;
  border-radius: var(--cas-radius-xs);
  background: var(--cas-bg-tag);
  display: flex; align-items: center; justify-content: center;
  margin: auto;
}
.cas-thumb-empty svg {
  width: 14px; height: 14px;
  color: var(--cas-text-muted); opacity: 0.5;
}

/* ─ 34.1 视频缩略图角标（区分图/视频，居中播放钮）─
 *  · 卡片型（容器已 position:relative）：容器内加 <span class="cas-video-badge"></span>
 *  · 表格小图（48×36，父是 td 无定位容器）：用 .cas-thumb-vwrap 包裹 video + <span class="cas-video-badge sm">
 */
.cas-video-badge {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 30px; height: 30px; border-radius: 50%;
  background: rgba(0,0,0,0.46);
  display: flex; align-items: center; justify-content: center;
  pointer-events: none; z-index: 2;
}
.cas-video-badge::before {
  content: ''; width: 0; height: 0;
  border-left: 9px solid #fff;
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  margin-left: 2px;
}
.cas-video-badge.sm { width: 16px; height: 16px; }
.cas-video-badge.sm::before {
  border-left-width: 5px;
  border-top-width: 3.5px; border-bottom-width: 3.5px;
  margin-left: 1px;
}
.cas-thumb-vwrap {
  position: relative; display: block;
  width: 48px; height: 36px; margin: auto;
  border-radius: var(--cas-radius-xs); overflow: hidden;
  background: var(--cas-bg-tag);
}
.cas-thumb-vwrap video { width: 100%; height: 100%; object-fit: cover; display: block; }


/* =============================================================================
 * 段配置卡片（meta.sections 单段折叠卡）
 *  · 由 /static/js/section-card-editor.js 渲染
 *  · schema editor 和 prompt-debug 共用
 * ============================================================================= */
.cas-sec-card {
  background: var(--cas-bg-white);
  border: 1px solid var(--cas-border);
  border-radius: 6px;
  margin-bottom: 6px;
}
.cas-sec-card-head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  background: var(--cas-bg-base);
  border-bottom: 1px solid var(--cas-border);
  border-radius: 6px 6px 0 0;
  cursor: pointer; user-select: none;
}
.cas-sec-card-collapsed .cas-sec-card-head {
  border-bottom: none; border-radius: 6px;
}
.cas-sec-card-head .arr {
  font-size: 10px; color: var(--cas-text-muted);
  transition: transform 0.18s;
}
.cas-sec-card-collapsed .cas-sec-card-head .arr { transform: rotate(-90deg); }
.cas-sec-card-key {
  font-family: ui-monospace, monospace; font-size: 12px;
  color: var(--cas-text-primary); font-weight: 600;
  flex: 1; overflow: hidden; text-overflow: ellipsis;
}
.cas-sec-card-tag {
  padding: 1px 6px; font-size: 10px; border-radius: 3px;
  color: var(--cas-text-muted);
  background: var(--cas-bg-tag);
  font-family: ui-monospace, monospace;
}
.cas-sec-card-tag.shared {
  background: rgba(var(--cas-accent-rgb), .14);
  color: var(--cas-accent-hover);
}
.cas-sec-card-actions { display: flex; gap: 4px; }
.cas-sec-card-actions button {
  background: transparent; border: 1px solid var(--cas-border);
  width: 22px; height: 22px; border-radius: 4px;
  cursor: pointer; font-size: 11px;
  color: var(--cas-text-secondary);
  display: inline-flex; align-items: center; justify-content: center;
}
.cas-sec-card-actions button:hover { background: var(--cas-bg-tag); color: var(--cas-text-primary); }
.cas-sec-card-actions button.del:hover { color: var(--cas-danger); border-color: var(--cas-danger); }
.cas-sec-card-body { padding: 10px; }
.cas-sec-card-collapsed .cas-sec-card-body { display: none; }
.cas-sec-card-label {
  font-size: 11px; font-weight: 600;
  color: var(--cas-text-muted);
  text-transform: uppercase; letter-spacing: 0.04em;
  margin: 8px 0 4px;
}
.cas-sec-card-body > div:first-child { margin-top: 0; }
.cas-sec-card-body input[type="text"] {
  width: 100%; padding: 5px 8px;
  border: 1px solid var(--cas-border);
  background: var(--cas-bg-white);
  color: var(--cas-text-primary);
  border-radius: 4px;
  font-family: ui-monospace, monospace;
  font-size: 12px;
}


/* =============================================================================
 * 主模板编辑区（meta.assembly_template）共用包装
 *  · schema editor + prompt-debug 共用一套外观（灰底外框 + 标题 + textarea + 可选 actions）
 * ============================================================================= */
.cas-master-template-wrap {
  background: var(--cas-bg-tag);
  border: 1px solid var(--cas-border);
  border-radius: 4px;
  padding: 8px 10px;
  margin-bottom: 10px;
}
.cas-master-template-head {
  color: var(--cas-text-muted);
  margin-bottom: 6px;
  font-size: 10px;
  display: flex; align-items: center; gap: 6px;
  flex-wrap: wrap;             /* 极端窄宽度下整行换，不断词中间 */
}
.cas-master-template-head strong {
  color: var(--cas-text-primary);
  font-size: 11px;
}
.cas-master-template-head .cas-master-template-hint {
  margin-left: auto;
  color: var(--cas-text-muted);
}
.cas-master-template-textarea {
  width: 100%; min-height: 140px;
  padding: 6px;
  border: 1px solid var(--cas-border);
  background: var(--cas-bg-white);
  border-radius: 3px;
  font-family: ui-monospace, monospace;
  font-size: 11px; line-height: 1.6;
  resize: vertical;
  color: var(--cas-text-primary);
}
.cas-master-template-actions {
  margin-top: 4px;
  display: flex; align-items: center; gap: 8px;
  justify-content: flex-end;
}


/* "未保存" 红色小 badge（inline 编辑场景用） */
.cas-unsaved-badge {
  font-size: 10px; color: var(--cas-danger);
  padding: 1px 6px; background: rgba(220, 53, 69, .12);
  border-radius: 3px; font-weight: 600;
}
