/* ============================================================
   apple.css · Apple 流体风格改造层（第 1 层：令牌 + 组件 + 动效）
   ------------------------------------------------------------
   定位：**覆盖层**，在 app.css 与 ds.css 之后加载。
   app.css 的 3,721 行一行不动 —— 删掉本文件的 <link> 即可完整回滚。

   为什么用覆盖层而不是改 app.css：
     27 个视图共用 app.css，直接改等于全站重构，风险不可控。
     覆盖层只改"表现"，不动任何结构与 JS，出问题能一键退回。

   保留品牌橙 #EF7F17（与 Logo 同色），只把它用得更克制 ——
   Apple 的做法是：中性色承担 90% 的界面，强调色只给"需要被看见的"。
   ============================================================ */

/* ---------- A. 设计令牌 ---------- */
:root {
  /* Apple 中性色阶：比原来的冷蓝灰更"中性"，不带色偏 */
  --ink:     #1D1D1F;   /* 主文字 */
  --ink-2:   #6E6E73;   /* 次文字 */
  --muted:   #86868B;   /* 辅助 */
  --faint:   #A1A1A6;   /* 三级辅助 */

  /* 分隔线改为半透明 —— 叠在不同底色上都自然，不会出现"白底白线" */
  --line:    rgba(0, 0, 0, .085);
  --line-2:  rgba(0, 0, 0, .045);

  --bg:      #F5F5F7;
  --card:    #FFFFFF;

  /* 填充（Apple 用半透明填充代替浅灰实色） */
  --fill:    rgba(120, 120, 128, .08);
  --fill-2:  rgba(120, 120, 128, .12);
  --fill-3:  rgba(120, 120, 128, .16);

  /* 品牌橙保持原值，只补充"橙色文字"达标色 */
  --brand:     #EF7F17;
  --brand-ink: #B4560A;

  /* 圆角整体放大一档 —— 这是"Apple 感"最直接的来源 */
  --r-xs: 8px;
  --r-sm: 10px;
  --r:    14px;
  --r-lg: 18px;
  --r-xl: 24px;

  /* 阴影：两层叠加（近处收紧轮廓 + 远处大扩散），透明度都很低 */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .04), 0 4px 12px rgba(0, 0, 0, .04);
  --shadow:    0 1px 2px rgba(0, 0, 0, .04), 0 6px 18px rgba(0, 0, 0, .05);
  --shadow-md: 0 2px 6px rgba(0, 0, 0, .05), 0 14px 36px rgba(0, 0, 0, .07);
  --shadow-lg: 0 4px 12px rgba(0, 0, 0, .06), 0 24px 60px rgba(0, 0, 0, .10);
  --shadow-xl: 0 6px 18px rgba(0, 0, 0, .07), 0 36px 90px rgba(0, 0, 0, .14);

  /* 弹簧曲线：替换全站 ease-out。0.32/0.72 是 Apple 常用的"微回弹" */
  --spring:      cubic-bezier(.32, .72, 0, 1);
  --spring-soft: cubic-bezier(.25, .8, .25, 1);
  --ease-io:     cubic-bezier(.32, .72, 0, 1);
  --ease-in:     cubic-bezier(.42, 0, 1, 1);
  --t-fast:      160ms;
  --t:           240ms;
  --t-slow:      360ms;
}

/* ---------- B. 全局基线 ---------- */
body {
  /* 系统字体优先（Apple 设备直接命中 SF Pro） */
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
               "PingFang SC", "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  letter-spacing: -.003em;
}

/* 焦点环：键盘可达性，用品牌色而非浏览器默认蓝 */
:focus-visible {
  outline: 0;
  box-shadow: 0 0 0 3px rgba(239, 127, 23, .28);
  border-radius: var(--r-xs);
}

/* ---------- C. 组件 ---------- */

/* --- C1. 卡片 --- */
.card,
.panel,
.sheet {
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  border-color: transparent;
}
.card:hover { box-shadow: var(--shadow-md); }

/* --- C2. 按钮：按下缩 4%，抬起带回弹 --- */
.btn {
  border-radius: var(--r-sm);
  font-weight: 590;
  letter-spacing: -.006em;
  transition: transform var(--t-fast) var(--spring),
              background-color var(--t-fast) var(--spring-soft),
              box-shadow var(--t) var(--spring-soft),
              color var(--t-fast);
  will-change: transform;
}
.btn:active { transform: scale(.96); }

.btn-primary {
  background: var(--brand);
  box-shadow: 0 1px 2px rgba(239, 127, 23, .22), 0 6px 16px rgba(239, 127, 23, .20);
}
.btn-primary:hover {
  background: #E5760F;
  box-shadow: 0 2px 4px rgba(239, 127, 23, .26), 0 10px 24px rgba(239, 127, 23, .26);
}
.btn-ghost {
  background: var(--fill);
  color: var(--ink);
  box-shadow: none;
}
.btn-ghost:hover { background: var(--fill-2); }
.btn-sm { border-radius: var(--r-xs); }
.btn-mini { border-radius: 7px; }

/* --- C3. 表格：去掉重边框，只留半透明分隔线 --- */
table thead th {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
}
table tbody td {
  border-bottom: 1px solid var(--line-2);
  transition: background-color var(--t-fast) var(--spring-soft);
}
table tbody tr:last-child td { border-bottom: 0; }
table tbody tr:hover td { background: var(--fill); }

/* 数字列：等宽 + 右对齐的视觉重心 */
table td.num,
table td[data-num],
.num {
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}

/* --- C4. 输入 / 下拉：填充式，聚焦时变白 + 橙色光环 --- */
.input,
.select,
textarea.input {
  background: var(--fill);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  transition: background-color var(--t-fast) var(--spring-soft),
              box-shadow var(--t) var(--spring),
              border-color var(--t-fast);
}
.input:hover,
.select:hover { background: var(--fill-2); }
.input:focus,
.select:focus,
textarea.input:focus {
  outline: 0;
  background: var(--card);
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(239, 127, 23, .16);
}

/* --- C5. 徽章 / 标签 --- */
.badge,
.pill,
.chip,
.tag {
  border-radius: 999px;
  font-weight: 600;
  letter-spacing: -.002em;
}

/* --- C6. 页签 / 分段：选中态用白色浮起，不用下划线 --- */
.tabs, .vtabs { border-bottom-color: var(--line); }
.tab {
  border-radius: var(--r-xs);
  transition: background-color var(--t-fast) var(--spring-soft),
              color var(--t-fast);
}
.tab:hover { background: var(--fill); }
.tab.active {
  background: var(--fill-2);
  color: var(--ink);
}

/* --- C7. KPI 卡：统一高度 + 数值基线对齐（沿用 v168 的结论，只换观感） --- */
.kpi {
  border-radius: var(--r);
  box-shadow: var(--shadow-sm);
  border-color: transparent;
  transition: box-shadow var(--t) var(--spring-soft),
              transform var(--t) var(--spring);
}
.kpi:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}

/* --- C8. 弹层 / 抽屉 / 模态：大圆角 + 强阴影 + 毛玻璃遮罩 --- */
.modal,
.dialog,
.drawer,
.sheet-panel {
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-xl);
}
.modal-mask,
.backdrop {
  background: rgba(0, 0, 0, .28);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

/* ---------- D. 交互反馈 ---------- */

/* 可点击行：hover 时轻微位移，暗示"可以点" */
tr[data-click]:hover,
.row-click:hover { transform: translateX(2px); }

/* 列表项进入：错峰淡入（最多 8 项，避免长列表延迟） */
@keyframes apl-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.kpi, .card { animation: apl-rise 320ms var(--spring) both; }
.kpi:nth-child(2) { animation-delay: 30ms; }
.kpi:nth-child(3) { animation-delay: 60ms; }
.kpi:nth-child(4) { animation-delay: 90ms; }
.kpi:nth-child(5) { animation-delay: 120ms; }
.kpi:nth-child(6) { animation-delay: 150ms; }

/* ---------- E. 无障碍 ---------- */
/* 尊重系统"减弱动态效果"：所有位移与缩放归零，只保留透明度变化 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .btn:active { transform: none; }
  .kpi:hover { transform: none; }
}

/* 尊重"提高对比度"：文字加深、分隔线加强 */
@media (prefers-contrast: more) {
  :root {
    --ink-2: #4A4A4F;
    --muted: #5A5A5F;
    --faint: #6E6E73;
    --line: rgba(0, 0, 0, .22);
    --line-2: rgba(0, 0, 0, .12);
  }
}

/* 高对比度下取消毛玻璃（避免文字与背景糊在一起） */
@media (prefers-contrast: more) {
  .modal-mask, .backdrop { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(0, 0, 0, .55); }
}

/* ---------- F. 登录页品牌面板 ---------- */
/* 主色仍是橙（用户要求），但换成"深橙 → 琥珀"的渐变而不是平铺亮橙：
   亮橙铺满半屏会显得廉价，深一档的焦糖橙更有质感，也更像 Apple 产品页的用色。
   右上角加一道暖光，左上角自然压深，形成从亮到深的体积感。 */
.auth-brand {
  background:
    radial-gradient(130% 96% at 76% 4%, rgba(255, 216, 175, .40) 0%, transparent 56%),
    radial-gradient(90% 70% at 8% 96%, rgba(120, 44, 0, .38) 0%, transparent 60%),
    linear-gradient(158deg, #B4530A 0%, #D9700F 44%, #F0954A 100%);
}
/* 刻度网格降到极淡，避免与文字抢注意力 */
.auth-brand::before {
  background-image:
    linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px);
}
/* 功能标签：毛玻璃小胶囊 */
.auth-feats span {
  background: rgba(255, 255, 255, .09);
  border: 1px solid rgba(255, 255, 255, .15);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  transition: background-color var(--t-fast) var(--spring-soft);
}
.auth-feats span:hover { background: rgba(255, 255, 255, .16); }
/* 登录页右侧：极浅的分隔，不用实线 */
.auth-panel { border-left: 1px solid var(--line-2); }

/* ============================================================
   G. 布局骨架（第 2 层）
   ------------------------------------------------------------
   顶栏本来就是毛玻璃、页面也有进入动画（.view.enter），所以这一层
   不重复造轮子，只做三件"质感细节"：

   1. 顶栏模糊从 12px 提到 20px、底色更透 —— 滚动时内容在下面流过更明显
   2. 侧栏从纯白改为极浅灰白（#FAFAFC），与内容区白卡形成层次；
      导航选中态从"橙底"改为"白卡 + 橙色左标 + 橙字"，
      因为大面积橙底在侧栏里连成一片会显得吵（Apple 侧栏选中态就是白底浮起）
   3. 内容区留白 24/28 → 28/32，卡片间距略放大 —— 更透气，但不牺牲数据密度
   ============================================================ */

/* --- G1. 顶栏：模糊更强、底色更透 --- */
.topbar {
  background: rgba(255, 255, 255, .72);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom-color: var(--line-2);
}

/* --- G2. 侧栏：极浅灰白，比纯白"轻"一档 --- */
.sidebar {
  background: #FAFAFC;
  border-right-color: var(--line-2);
}

/* --- G3. 导航项：Apple 侧栏手感 --- */
.nav-item {
  border-radius: 10px;
  transition: background-color var(--t-fast) var(--spring-soft),
              color var(--t-fast) var(--spring-soft),
              box-shadow var(--t) var(--spring-soft),
              transform var(--t-fast) var(--spring);
}
.nav-item:hover { background: var(--fill); }
.nav-item:active { transform: scale(.985); }

/* 选中态：白卡浮起 + 橙色左标 + 橙字（不再是整块橙底） */
.nav-item.active {
  background: var(--card);
  color: var(--brand-ink);
  font-weight: 650;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 4px 12px rgba(0, 0, 0, .05);
}
.nav-item.active::before {
  background: var(--brand);
  width: 3px;
  border-radius: 0 3px 3px 0;
}

/* --- G4. 内容区：留白略放大 --- */
.view { padding: 28px 32px 80px; }
@media (max-width: 860px) {
  .view { padding: 20px 16px 72px; }
}

/* --- G5. 卡片间距：更疏朗（不改列数） --- */
.card + .card,
.card + .grid,
.grid + .card { margin-top: var(--sp-4); }

/* 分组内的模块级子项：选中态保持轻量（浅橙底、无阴影），
   否则侧栏里会同时浮起好几块白卡，反而更乱 */
.sb-group-bd .nav-item.active {
  background: var(--brand-50);
  color: var(--brand-ink);
  font-weight: 600;
  box-shadow: none;
}

/* ============================================================
   H. 第 3 层 · 页面骨架细化
   ------------------------------------------------------------
   盘点发现骨架类（.empty 253 处 / .toolbar 45 处 / .sk 骨架屏）本来就有，
   不需要重建。这里只做三件"覆盖全站"的细化，性价比高于逐页改 27 个视图。
   ============================================================ */

/* --- H1. 空态：从"一行灰字"变成"有分量的引导位" --- */
.empty { padding: 64px 24px; }
.empty svg {
  width: 26px; height: 26px;
  padding: 14px; box-sizing: content-box;
  background: var(--fill);
  border-radius: 50%;
  stroke: var(--muted);
  margin-bottom: 16px;
}
.empty b {
  font-size: 16px;
  font-weight: 650;
  color: var(--ink);
  margin-bottom: 6px;
  letter-spacing: -.01em;
}

/* --- H2. 表格行操作：hover 才浮现（Apple 表格的常见做法）---
   只在支持 hover 的设备上隐藏 —— 触屏没有 hover，
   一刀切隐藏会让手机用户永远点不到操作按钮。 */
/* 保守做法：只降到 55% 而不是完全隐藏。
   原因：.row-actions 有 24 处用法，不能保证每一处都在 <tr> 里；
   若某处位于卡片/工具栏内，opacity:0 会让按钮永久消失。 */
@media (hover: hover) and (pointer: fine) {
  tr .row-actions {
    opacity: .55;
    transition: opacity var(--t-fast) var(--spring-soft);
  }
  tr:hover .row-actions,
  tr:focus-within .row-actions { opacity: 1; }
}
.row-actions:focus-within { opacity: 1 !important; }

/* ============================================================
   I. 第 4 层 · 交互手感
   ============================================================ */

/* --- I1. 弹层：从中心轻微放大出现（带一点回弹），关闭更快 --- */
@keyframes apl-modal-in {
  from { opacity: 0; transform: scale(.965) translateY(10px); }
  to   { opacity: 1; transform: scale(1) translateY(0); }
}
.modal {
  animation: apl-modal-in 340ms var(--spring) both;
}
.modal-mask {
  animation: apl-fade 200ms var(--spring-soft) both;
}
@keyframes apl-fade { from { opacity: 0 } to { opacity: 1 } }

/* --- I2. 抽屉：从边缘滑入 + 动量收尾 --- */
@keyframes apl-drawer-right { from { transform: translateX(24px); opacity: 0 } to { transform: none; opacity: 1 } }
@keyframes apl-drawer-bottom { from { transform: translateY(24px); opacity: 0 } to { transform: none; opacity: 1 } }
.drawer { animation: apl-drawer-right 360ms var(--spring) both; }
.drawer.bottom, .sheet { animation: apl-drawer-bottom 380ms var(--spring) both; }

/* --- I3. 行点击反馈：按下时整行轻微内缩，给"点到了"的确认 --- */
tr[data-click]:active,
.row-click:active { transform: scale(.997); }

/* --- I4. 批量操作浮条：从底部升起（若存在）--- */
@keyframes apl-rise-bar { from { transform: translateY(100%); opacity: 0 } to { transform: none; opacity: 1 } }
.bulk-bar, .batch-bar, .selection-bar {
  animation: apl-rise-bar 300ms var(--spring) both;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  box-shadow: var(--shadow-lg);
}

/* --- I5. 下拉/浮层：从锚点方向展开 --- */
@keyframes apl-pop { from { opacity: 0; transform: translateY(-4px) scale(.98) } to { opacity: 1; transform: none } }
.popover, .dropdown, .menu-pop { animation: apl-pop 200ms var(--spring) both; }

/* --- I6. 减弱动效下：所有新增动效一并归零 --- */
@media (prefers-reduced-motion: reduce) {
  .modal, .modal-mask, .drawer, .sheet, .bulk-bar, .batch-bar, .selection-bar, .popover, .dropdown {
    animation: none !important;
  }
}

/* ============================================================
   J. 字体系统（Apple 字阶 · 统一表单字号）
   ------------------------------------------------------------
   审计发现的问题：
     .label  12px  ┐
     .input  14px  ├─ 同一个表单里三种字号，看着就是"大小不一"
     .select 12px  ┘
     .input 另有一处 16px（应为 iOS 防缩放的历史遗留）

   为什么不全部统一成 14px：
     表格内也大量使用 .input/.select（采购 44 处、招聘 47 处），
     全局放大到 14 会撑高行高、破坏数据密度。
     → 所以**只统一"表单区"，表格内保持紧凑**。

   Apple 字阶（本项目适配版，按用途固定，不允许随手加新值）：
     --fs-1  11px  角标 / 极小标注
     --fs-2  12px  辅助说明（caption）
     --fs-3  13px  表单标签 / 表格次要文字（footnote）
     --fs-4  14px  表格正文 / 紧凑控件
     --fs-5  15px  表单控件 / 正文（body）
     --fs-6  17px  强调正文（headline）
     --fs-7  20px  卡片标题（title3）
     --fs-8  24px  页面标题 / 大数字（title2）
     --fs-9  29px  KPI 主数字（large title）
   ============================================================ */

/* --- J1. 字体栈：显式写出 SF Pro，Apple 设备上直接命中 --- */
html {
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
               "Helvetica Neue", "PingFang SC", "Hiragino Sans GB",
               "Microsoft YaHei", Arial, sans-serif;
  /* 等宽数字用于表格与 KPI，避免数字跳动 */
  font-feature-settings: "kern" 1;
  text-rendering: optimizeLegibility;
}

/* --- J2. 字阶：只修一个值，不做整体放大 ---
   ⚠ 我一开始把整条字阶放大了 1–2px（对齐 Apple 的 body 17px），但评估后撤回：
     这是数据密集的管理系统，整体放大 2px 会让表格行变高、一屏能看的数据变少。
     用户说的是"大小不一"（一致性问题），不是"字太小"（可读性问题）——
     这两件事要分开决策，不能顺手一起改。

   只改一处：--fs-1 从 10px → 11px。
     10px 在 2x 屏（MacBook / 现代笔记本）上已经低于可读下限，
     而 11px 是整条字阶里唯一"确实太小"的一档。

   要不要整体放大（比如正文 14→15、表格 13→14），需要单独确认。 */
:root {
  --fs-1: 11px;   /* 原 10 —— 唯一保留的调整 */
}

/* --- J3. 表单区：所有控件统一 15px（消除 input/select 不一致）--- */
.field .input,
.field .select,
.field textarea,
.form-grid .input,
.form-grid .select,
.form-row .input,
.form-row .select,
.modal .field .input,
.modal .field .select,
.drawer .input,
.drawer .select {
  font-size: var(--fs-5);
  line-height: 1.45;
}

/* --- J4. 表单标签：13px / 600，与控件拉开一个台阶 --- */
.field label,
.field .label,
.form-grid .label {
  font-size: var(--fs-3);
  font-weight: 600;
  color: var(--ink-2);
  letter-spacing: -.002em;
}

/* --- J5. 提示与帮助文字：12px，颜色退一档，不与正文抢 --- */
.field .hint,
.field .help,
.field .sub,
.field .tip {
  font-size: var(--fs-2);
  color: var(--muted);
  line-height: 1.5;
}

/* --- J6. 表格内控件：保持紧凑，不随表单一起放大 --- */
td .input,
td .select,
table .input,
table .select {
  font-size: var(--fs-4);
  padding-top: 4px;
  padding-bottom: 4px;
}

/* --- J7. 移动端：控件提到 16px，否则 iOS Safari 聚焦时会强制放大页面 --- */
@media (max-width: 860px) {
  .field .input,
  .field .select,
  .field textarea,
  .form-grid .input,
  .form-grid .select {
    font-size: 16px;
  }
}

/* --- J8. 数字统一等宽：表格数值、KPI 数字、金额 --- */
td.num,
.num,
.kpi .k-val,
.kpi .kv,
td .money,
.amount {
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}

/* ============================================================
   K. 第 5 层 · 看板等高 / 留白治理
   ------------------------------------------------------------
   用户第 3 次反馈「看板没对齐、卡片下方一大片空白」。1440×900 下用
   Playwright 逐页量 getBoundingClientRect，定位到 4 个真实成因，
   全部落在"表现层"，因此全部在本覆盖层解决（app.css 与所有 JS 一行不动）：

   成因①【同排错位 16px】→ K1（这是"没对齐"的真正来源）
     G5 的 `.card + .card { margin-top: var(--sp-4) }` 本意是给"上下叠放的两张
     卡片"留出间距，但它同样命中 **grid 容器内部** —— 而 grid 的间距早已由 gap
     提供，于是这条 margin 变成"同排第二张卡整体下沉 16px"。
     实测（修复前）：采购 / 库存 / 资产 / 员工结构 的每一排 topOff 都是 16px，
     左卡顶边 703、右卡顶边 719；因为卡片高度被 stretch 拉平，
     底边也随之错开 16px —— 看上去就是一排"斜着的卡"。

   成因②【被拉高后底部空洞】→ K3/K4
     Grid 默认 align-items:stretch，同一排的卡被拉到该排最高卡的高度。
     等高本身是对的（用户要的"等高"），问题在于"多出来的高度没人吃"：
     内容只有一行的卡，多出来的部分全堆在内容下方。
     解法不是放弃等高，而是让内容去吸收高度：
       · 图表卡：图区 flex:1 + 竖直居中，图在卡内居中，视觉上"填满"
       · 空状态卡：空态竖直居中，不再出现"顶上一个'无'、下面一片白"

   成因③【空态卡片本身过高】→ K5
     `.empty` 的 64px 上下内边距，让"只有一个'无'字"的卡片也撑出 128px。

   成因④【双列里的右列永远比左列矮】→ K6
     左列是"表格卡 + 图表卡"的纵向堆叠，右列是若干小卡堆叠；
     两列等高，但列内最后一张卡不会补足剩余高度，于是左列末尾空一截。

   一个总原则：**等高要保留，留白要靠"内容吸收高度"消灭，而不是靠放弃等高。**
   ============================================================ */

/* --- K1. 栅格内部不再叠加 margin：同排 / 同列卡片顶边必须齐平 ----------
   注意选择器写法：app.css 里原规则是 `.card + .card`（两个类），
   单写 `.grid > * + *`（一个类）在层叠里赢不了它，所以这里用
   `.grid.grid > * + *` 这类"同类名重复"的写法把权重提到同一档，
   再靠 apple.css 靠后加载的顺序胜出 —— 全程不需要 !important。 */
.grid.grid > * + *,
.wb-grid.wb-grid > * + *,
.ast-two.ast-two > * + *,
.inbox-grid.inbox-grid > * + *,
.ss-grid.ss-grid > * + *,
.fc-flowgrid.fc-flowgrid > * + *,
.sv-grid.sv-grid > * + * {
  margin-top: 0;
}

/* `.stat-2col` 单独处理，且必须清**所有**子项（`> *`），不能只清 `* + *`：
   它的子项是 `.stat-block`，app.css 给 `.stat-block` 自带 `margin-top:14px`。
   只清第二项会让第一项仍带 14px，容器又是 `align-items:start`（不做跨行补偿），
   结果右栏整体上浮 14px —— 这正是 v171 在考勤统计页引入的 14px 错位回归
   （实测 topOff 0 → 14，三排）。清干净后两栏顶边重新齐平。 */
.stat-2col.stat-2col > * {
  margin-top: 0;
}

/* --- K2. 同行等高：Grid 默认就是 stretch，这里不再重复声明 ---
   踩过的坑：早先写过一条 `.grid.grid > * { align-self: stretch }`，
   权重(0,2,0) 反而盖掉了 K4 里 `.card:has(table) { align-self: start }`
   这类(0,1,1) 的例外规则，导致"表格卡按内容高度"完全失效、白块照旧。
   结论：等高交给 Grid 默认值，只在需要"例外"的地方显式写。
   KPI 指标行的子项默认就是拉伸态，同样无需声明。 */

/* --- K3. 图表卡片：被拉高时由图表区吃掉多余高度 ---
   `.card.chart-card` 是采购图表卡的既有类名；
   `.card:has(> .chart-bd)` 覆盖"没写 chart-card 但挂了图表体"的卡片。
   只声明卡片自己是 flex 列，不动容器的 align-items，
   所以不会和视图里 7 处内联 `align-items:start` 打架，也不需要 !important。 */
.card.chart-card,
.card:has(> .chart-bd) {
  display: flex;
  flex-direction: column;
  align-self: stretch;   /* 视图里若有内联 align-items:start，图表卡仍要等高 */
}
.card.chart-card > .chart-bd,
.card:has(> .chart-bd) > .chart-bd {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* --- K4. 空状态 / 表格卡片：按内容高度，不参与行拉伸 ---
   用户原话：「近效期卡片内容只有"无"一个字，却被拉得和右边表格一样高」。
   这类卡片的内容长度天然差得远（1 行 vs 8 行），一旦被拉高，
   多出来的高度只能变成白块 —— 所以让它们贴住自己的内容，
   宁可底边不齐，也不留白块。

   这里用 `:has(table)` 而不是类名，是为了不依赖"表格外层容器叫什么"：
   colcfg.js 在运行期会**新建**一个 `.tbl-shell`，把原来的 `.tbl-wrap`
   **包起来**再塞列设置按钮（colcfg.js:244-252，`.tbl-wrap` 类名本身仍在）。
   也就是说表格外层可能是 `.tbl-wrap`，也可能是 `.tbl-shell`，还可能直接是
   `.card-bd`；只认 `<table>` 元素最稳，也省得以后外层再改一次名就失效。 */
.card:has(table),
.card:has(.empty) {
  align-self: start;
}

/* --- K4b. 图形 / 图表类卡片体：被拉高时竖直居中 ---
   库存「库龄分布」(.agebars)、员工结构「用工类型构成」(.bar-row)、
   资产「状态分布」(.ast-bars)、资产盘点「近 12 个月趋势」(.ast-trend) …
   这些都不是 .chart-bd，但同样是"图"。
   v171 最初是逐个枚举类名，结果漏了 .ast-trend（盘点页右卡留下 112px 白，
   比修复前还多 16px）。现在改成**按结构判定**：卡片体里既没有表格、也没有
   空态，就视为图形区 —— 以后新增任何图表类名都自动覆盖，不会再漏。

   ⚠ 写法有坑：`:has()` **不能嵌套在 `:has()` 内部**（CSS 规范明确禁止），
   最初写成 `.card:has(> .card-bd:not(:has(table)))` 时整条规则被浏览器
   直接丢弃（不报错、静默失效），P2 因此"改了却没生效"。
   正确写法是把否定提到外层：`.card:has(> .card-bd):not(:has(table))`。 */
.card:has(> .card-bd):not(:has(table)):not(:has(.empty)) {
  display: flex;
  flex-direction: column;
}
.card:has(> .card-bd):not(:has(table)):not(:has(.empty)) > .card-bd {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* --- K4c. 空态卡片：若因场景需要被拉高（工作台三卡并列），空态竖直居中 --- */
.card:has(> .empty),
.card:has(> .card-bd > .empty) {
  display: flex;
  flex-direction: column;
}
.card:has(> .empty) > .empty,
.card:has(> .card-bd > .empty) > .card-bd {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* --- K4d. 工作台三卡并列（最近通知 / 我的待办 / 快捷入口）：保持等高 ---
   这一行是同构 widget，等高更像一个整体；空态由 K4c 居中，
   不会出现"顶上一个字、下面一大片白"。 */
.wb-grid > .card {
  align-self: stretch;
}

/* --- K5. 空状态尺寸：不再把"一个'无'字"撑成一屏 ---
   ⚠ 这是**全局**改动，不是局部：`.empty` 在全站有 256 处直接写法
   （另有 emptyMini() 等封装调用 30 处），改它等于所有空态一起变紧。
   64px → 40px（上下）是刻意为之：空态是"没有数据"的提示，不该占掉半屏；
   若将来要区分"页面级空态"和"卡片内空态"，请新增更细的选择器，
   不要在这里加例外。 */
.empty {
  padding: var(--sp-8) var(--sp-6);
}

/* --- K6. 双列栅格里的纵向列：最后一张卡补足剩余高度 ---
   典型：采购驾驶舱「月度预算执行 + 品类分布」左列 vs 「最新动向 + 待办」右列。
   把列容器变成 flex 列（间距交给 gap，避免与 .card + .card 的 margin 叠加），
   列内最后一张卡吃掉剩余高度 —— 于是左右两列底边齐平。 */
.grid.g2 > div:not(.card):not(.kpi):not(.panel) {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  align-self: stretch;          /* 列容器先撑满整行高度，列内才能补高 */
}
.grid.g2 > div > .card {
  margin-top: 0;                /* 间距交给上面的 gap，避免 16px 叠加 */
}
.grid.g2 > div > .card:last-child {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
/* 被补高的那张卡：卡片体吃掉剩余高度（表格/空态不参与补高，避免白块） */
.grid.g2 > div > .card:last-child > .card-bd,
.grid.g2 > div > .card:last-child > .chart-bd {
  flex: 1 1 auto;
  min-height: 0;
}
.grid.g2 > div > .card:last-child:has(table),
.grid.g2 > div > .card:last-child:has(.empty) {
  flex: 0 0 auto;
}

/* --- K7. 移动端 / 窄屏：单列堆叠，一切回到"按内容高度" --- */
@media (max-width: 860px) {
  .grid.grid > *,
  .wb-grid.wb-grid > *,
  .ast-two.ast-two > * {
    align-self: auto;
  }
  .card.chart-card > .chart-bd,
  .card:has(> .chart-bd) > .chart-bd,
  .card > .empty,
  .card:has(> .card-bd > .empty) > .card-bd {
    flex: 0 0 auto;
    justify-content: flex-start;
  }
  .grid.g2 > div:not(.card):not(.kpi):not(.panel) {
    display: block;
  }
  .grid.g2 > div > .card:last-child {
    flex: 0 0 auto;
  }
  /* 单列下 `.card + .card` 的 16px 间距是必要的，恢复它 */
  .grid.g2 > div > .card + .card {
    margin-top: var(--sp-4);
  }
}

/* ============================================================
   K8 / K9 · KPI 行的两处收尾（v171.1）
   ============================================================ */

/* --- K8. KPI 金额不再被省略号截断 ---
   成因：ds.css:938-943 为了"长数字不撑破卡片"加了
   `.k-val { white-space:nowrap; overflow:hidden; text-overflow:ellipsis }`，
   于是一旦金额超过卡片宽度就显示成 `6,740,000.0…` —— 数字最重要的信息被吃掉了。
   解法：把 KPI 卡变成查询容器，字号按**卡片宽度**自适应（cqi），
   让长金额自动缩号而不是截断；同时收紧字距，多放一位。
   系数说明：cqi 是**查询容器内容盒**的百分比（不是 border-box）。
   6 列时卡片 178px、内容盒 140px，14cqi ≈ 19.6px ——
   实测 12 字符金额（6,740,000.00）在 140px 内刚好完整；宽屏卡片自动放大，
   上限仍是原来的 --fs-9(29px)，不会比改动前更大。
   包在 @supports 里：不支持容器查询的浏览器继续走原来的省略号逻辑，
   不会出现"文字被硬裁掉"的更差结果。 */
@supports (container-type: inline-size) {
  .kpis > .kpi,
  .wb-kpis > .kpi,
  .tw-kpis > .tw-kpi {
    container-type: inline-size;
  }
  .kpis > .kpi .k-val,
  .wb-kpis > .kpi .kv,
  .tw-kpis > .tw-kpi b {
    overflow: visible;
    text-overflow: clip;
    font-size: clamp(17px, 14cqi, var(--fs-9));
    letter-spacing: -.045em;
  }
}

/* --- K9. 六项 KPI 一行排满（第 6 张不再掉到第二行） ---
   实测：`.view` 内容盒 1130px，`.kpis` 的 minmax(184px,1fr) 需要
   6×184+5×12=1164px，放不下 → 只剩 5 列，第 6 张孤零零落在第二行最左，
   右边空出 930px，看起来像"漏了一张卡"。
   把这类容器的最小列宽压到 158px 即可一行 6 张（6×158+60=1008 ≤ 1130）。
   带 k6 / kpis6 的容器（采购、库存、财务、法务、团队、资产）本来就显式
   写好了六列栅格与 1360px 断点，这里用 :not() 排除，绝不覆盖它们的响应式规则。 */
.kpis:has(> .kpi:nth-child(6)):not(.k6):not(.kpis6) {
  grid-template-columns: repeat(auto-fit, minmax(min(158px, 100%), 1fr));
}

/* ============================================================
   L. 12 列网格系统（方案 A · Step 1）
   ------------------------------------------------------------
   目的：给全站一个统一的网格基准，替代现在 80+ 种不同的
        grid-template-columns 和 8 种 gap。

   ★ 作用域隔离：本段所有规则只在 .grid-12 容器内生效。
     现有 27 个视图用的是 .grid / .g2 / .g3 / .kpis，完全不受影响。
     迁移一页，才有一页用上新网格；出问题只影响已迁移的页面。

   为什么用 12 列：
     3/4/6/8/12 五种跨度都能整除 12，任意组合都能对齐。
     这是 react-grid-layout / Bootstrap / Ant Design 的同一套基准。
   ============================================================ */

/* --- L1. 网格令牌 --- */
:root {
  --grid-cols: 12;
  --grid-gap: 16px;          /* 卡片间距，全站唯一值（原 8 种 → 1 种） */
  --grid-row: 140px;         /* 基础行高：内容少的卡片最小高度 */
  --card-pad: 20px;          /* 卡片内边距，唯一值 */
}

/* --- L2. 网格容器 --- */
.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--grid-gap);
  /* 行高：最小 140px，内容多时可撑高；同行卡片由 stretch 自动等高 */
  grid-auto-rows: minmax(var(--grid-row), auto);
  align-items: stretch;
  min-width: 0;
}

/* --- L3. 跨度档位（3/4/6/8/12，按用户确认） --- */
.col-3  { grid-column: span 3; }
.col-4  { grid-column: span 4; }
.col-6  { grid-column: span 6; }
.col-8  { grid-column: span 8; }
.col-12 { grid-column: span 12; }

/* 纵向跨行（可选：内容确实需要更高时用） */
.row-2 { grid-row: span 2; }
.row-3 { grid-row: span 3; }

/* --- L4. 响应式：列数递减，span 按比例折算（百分比永远不变） --- */
@media (max-width: 1199px) {
  .grid-12 { grid-template-columns: repeat(8, minmax(0, 1fr)); }
  .col-3  { grid-column: span 2; }   /* 2/8  = 25% */
  .col-4  { grid-column: span 3; }   /* 3/8  ≈ 37% */
  .col-6  { grid-column: span 4; }   /* 4/8  = 50% */
  .col-8  { grid-column: span 5; }   /* 5/8  ≈ 62% */
  .col-12 { grid-column: span 8; }
}

@media (max-width: 991px) {
  .grid-12 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .col-3  { grid-column: span 2; }   /* 2/6 ≈ 33% */
  .col-4  { grid-column: span 2; }
  .col-6  { grid-column: span 3; }   /* 3/6 = 50% */
  .col-8  { grid-column: span 4; }   /* 4/6 ≈ 67% */
  .col-12 { grid-column: span 6; }
}

@media (max-width: 767px) {
  .grid-12 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .col-3, .col-4, .col-6 { grid-column: span 2; }   /* 两两并排 */
  .col-8, .col-12        { grid-column: span 4; }   /* 整行 */
}

@media (max-width: 479px) {
  .grid-12 { grid-template-columns: 1fr; }
  .col-3, .col-4, .col-6, .col-8, .col-12 { grid-column: span 1; }
  .row-2, .row-3 { grid-row: auto; }                /* 单列下取消跨行 */
}

/* --- L5. 卡片三段结构（只在 .grid-12 内生效）---
   目标：同一行等高 + 内容少时居中不显空 + 内容多时内部滚动不撑破 */
.grid-12 > .card,
.grid-12 > div > .card {
  display: flex;
  flex-direction: column;
  min-height: var(--grid-row);
  min-width: 0;                 /* 防止 grid 子项被内容撑破 */
  overflow: hidden;             /* 配合内部滚动，避免圆角处溢出 */
}

/* 头部：固定高度，不参与伸缩 */
.grid-12 > .card > .card-hd,
.grid-12 > div > .card > .card-hd { flex: 0 0 auto; }

/* 主体：吃掉剩余高度；内容超出时内部滚动，不把整行撑高 */
.grid-12 > .card > .card-bd,
.grid-12 > .card > .chart-bd,
.grid-12 > div > .card > .card-bd,
.grid-12 > div > .card > .chart-bd {
  flex: 1 1 auto;
  min-height: 0;                /* flex 子项能收缩的关键 */
  overflow-y: auto;
}

/* 空态：垂直居中，空白均分上下（而不是全堆在底部） */
.grid-12 > .card > .empty,
.grid-12 > div > .card > .empty {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 0;
}

/* --- L6. 列容器（.grid-12 里包一层 div 再放多张卡的场景）---
   如采购页左列：近效期 → 类别分布 → 待办，三张卡纵向堆叠 */
.grid-12 > div:not(.card) {
  display: flex;
  flex-direction: column;
  gap: var(--grid-gap);
  min-width: 0;
  min-height: 0;
}

/* 列内最后一张卡吸收剩余高度，避免列底露出页面底色（灰缝） */
.grid-12 > div:not(.card) > *:last-child {
  flex: 1 1 auto;
}

/* 列内的卡片也要能撑满（覆盖 .card 默认的 min-height） */
.grid-12 > div:not(.card) > .card {
  min-height: 0;
}

/* --- L7. 表格卡例外：允许表格自然撑高，不强制滚动 ---
   表格滚动体验差（用户要一屏看 30 行），所以表格卡不设 overflow。
   高度仍由 grid 保证同行等高。 */
.grid-12 > .card:has(> .card-bd table),
.grid-12 > div > .card:has(> .card-bd table) > .card-bd {
  overflow-y: visible;
}

/* ============================================================
   M. 修正：`.card + .card` 在网格容器内重复计算间距（第 3 次踩同一个坑）
   ------------------------------------------------------------
   历史：
   - v175 我加了 G5 `.card + .card { margin-top: 16px }`（本意给纵向叠放卡留间距）
   - v178 在 K1 里用 `.grid.grid > * + *` 清零 —— **只覆盖了 `.grid`**
   - v179 新增 `.grid-12`，又没覆盖 → 同排第 2/3/4 张卡再次下沉 16px
     实测（测试页第一行四张 col-3）：A top=24，B/C/D top=40 —— 正好差一个 gap

   ★ 这次不再逐个容器打补丁，改为给 G5 加"排除网格容器"的条件：
     只要容器 class 含 "grid" 或 "cols-"，内部相邻卡片的 margin-top 一律归零，
     间距全部交给 gap。以后新增任何网格容器都自动正确。
   ============================================================ */
[class*="grid"] > .card + .card,
[class*="grid"] > * > .card + .card,
[class*="cols-"] > .card + .card,
[class*="cols-"] > * > .card + .card,
.kpis > .kpi + .kpi,
.kpis > * + * {
  margin-top: 0;
}

/* 同理：卡片与网格容器相邻时也不叠加 margin（间距由外层容器的 gap 负责） */
[class*="grid"] > .card + [class*="grid"],
[class*="grid"] > [class*="grid"] + .card {
  margin-top: 0;
}

/* --- L8. 工作台卡片组：按卡片数量自动均分跨度 ---
   工作台主网格有 3 或 4 张卡（"我的申请"按权限条件渲染）：
   4 张 → 各 3/12（一行四列）；3 张 → 各 4/12（一行三列）。
   用 :has() 数卡片数量，不需要在 JS 里判断，卡片增删自动适配。 */
.grid-12.wb-cards > .card { grid-column: span 4; }                       /* 默认 3 列 */
.grid-12.wb-cards:has(> .card:nth-child(4)) > .card { grid-column: span 3; }  /* 4 张时改 4 列 */

/* --- L9. 流程全景卡片：补内边距 ---
   根因：.card 本身不带 padding（padding 在 .card-hd/.card-bd 上），
   而 .fc-flowcard 把内容直接放在 .card 里，所以标题和节点链都贴着卡片边。
   对比：其它卡片的正文都在 .card-bd 里，所以有 18-20px 内边距。 */
.fc-flowcard {
  padding: 14px 16px;
  gap: 12px;                                  /* 原来 10px，标题与节点链之间多留一口气 */
}
.fc-flowcard .fc-flow-hd { gap: 12px; }        /* 原来 8px，标题与徽章之间太挤 */
.fc-flowcard .fc-flow-hd b {
  font-size: var(--fs-5);
  line-height: 1.35;
  min-width: 0;                                /* 允许长标题收缩，而不是把徽章挤出去 */
}
/* 徽章不参与压缩，始终完整显示 */
.fc-flowcard .fc-flow-hd .badge { flex: 0 0 auto; white-space: nowrap; }
/* 节点链在窄卡片里换行，不撑破 */
.fc-flowcard .fc-chain { gap: 6px 6px; }

/* --- L10. 修正：flex 列容器内的卡片必须撑满宽度 ---
   ★ 真正的灰带根因（用户反馈第 5 次才找到）：
     v178 的 K4 段为了修「表格卡/空态卡被拉伸留白」，给它们加了
       .card:has(table), .card:has(.empty) { align-self: start }
     在 **grid 容器**里，align-self 控制的是「垂直方向」（高度按内容）—— 这是想要的。
     但在 **flex column 容器**（.grid-12 的列容器）里，
     align-self 控制的是「水平方向」（宽度）→ 卡片宽度变成内容宽度，
     于是在宽列里露出一大片页面底色 = 用户看到的灰带。

   修法：在 flex 列容器内强制 stretch 宽度，高度仍由 flex 分配。 */
.grid-12 > div:not(.card) > .card,
.grid-12 > div:not(.card) > * > .card {
  align-self: stretch;
  width: auto;              /* 覆盖可能存在的 width: fit-content / max-content */
  min-width: 0;
}

/* --- L11. 资产页 .ast-two 纳入 12 列网格 ---
   资产页有 4 处 <div class="two ast-two">（原 1fr 1fr，gap 16）。
   只在 CSS 层覆盖，不动 JS —— 4 处同时受益，符合最小改动原则。
   同时补上「卡片撑满列容器」：理由同 L10（align-self 在 flex 里的语义）。 */
.ast-two {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--grid-gap);
  margin-bottom: 16px;              /* 保留原间距 */
}
.ast-two > * { grid-column: span 6; }

/* 卡片结构：撑满宽度 + 主体吃剩余高度 */
.ast-two > .card {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  min-width: 0;
  min-height: var(--grid-row);
}
.ast-two > .card > .card-bd,
.ast-two > .card > .chart-bd { flex: 1 1 auto; min-height: 0; }
.ast-two > .card > .empty { flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; }

/* 响应式：与 .grid-12 同一套断点 */
@media (max-width: 991px) {
  .ast-two { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .ast-two > * { grid-column: span 6; }        /* 单列（6/6） */
}
@media (max-width: 479px) {
  .ast-two { grid-template-columns: 1fr; }
  .ast-two > * { grid-column: span 1; }
}

/* ============================================================
   N. Apple 风下拉选框（方案 C · 零侵入增强）
   ------------------------------------------------------------
   原生 <select> 保留在 .asel 内（class = asel-native，视觉隐藏），
   上面叠 .asel-btn + .asel-pop 两层自定义 UI。
   删掉 index.html 里的 apple-select.js 引用即可完整回滚。

   规格（与 docs/select-apple-demo.html 一致）：
     触发器  h 40 · r 10 · border rgba(0,0,0,.10) · shadow 0 1px 2px
     面板    r 14 · blur(24px) saturate(180%) · 双层阴影
     选项    h 36 · r 8 · hover rgba(0,113,227,.10) · 选中 #0071E3 + 白勾
     动效    scale(.96→1) translateY(-4→0) · cubic-bezier(.34,1.56,.64,1) 260ms
   ============================================================ */

/* --- N1. 容器：宽度跟随原 select（原 select 多为 width:100%） --- */
.asel {
  position: relative;
  display: block;
  width: 100%;
  min-width: 0;
}
/* 原生 select 视觉隐藏但保留功能（表单值 / 无障碍树） */
.asel > select.asel-native {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}

/* --- N2. 触发器 --- */
.asel-btn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  height: 40px;
  padding: 0 11px 0 13px;
  font: inherit;
  font-size: var(--fs-5);
  line-height: 1.2;
  color: var(--ink);
  text-align: left;
  background: var(--card);
  border: 1px solid rgba(0, 0, 0, .10);
  border-radius: 10px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
  cursor: pointer;
  transition: border-color .16s cubic-bezier(.4, 0, .2, 1),
              box-shadow .16s cubic-bezier(.4, 0, .2, 1),
              transform .12s cubic-bezier(.34, 1.56, .64, 1);
}
.asel-btn:hover { border-color: rgba(0, 0, 0, .18); }
.asel-btn:active { transform: scale(.985); }
.asel.open .asel-btn {
  border-color: #0071E3;
  box-shadow: 0 0 0 3.5px rgba(0, 113, 227, .16);
}
.asel-btn:focus-visible {
  outline: none;
  border-color: #0071E3;
  box-shadow: 0 0 0 3.5px rgba(0, 113, 227, .16);
}

.asel-val {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.asel-val.ph { color: var(--muted); }

.asel-chev {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  display: inline-flex;
  color: var(--muted);
  transition: transform .26s cubic-bezier(.34, 1.56, .64, 1);
}
.asel-chev svg { width: 100%; height: 100%; display: block; }
.asel.open .asel-chev { transform: rotate(180deg); }

/* --- N3. 展开面板 --- */
.asel-pop {
  position: fixed;
  z-index: 9999;          /* 面板挂在 body 下，需盖过 .modal-mask(500) 与 toast */
  padding: 6px;
  background: rgba(252, 252, 253, .82);
  -webkit-backdrop-filter: saturate(180%) blur(24px);
  backdrop-filter: saturate(180%) blur(24px);
  border-radius: 14px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .06),
              0 12px 36px rgba(0, 0, 0, .16),
              0 2px 6px rgba(0, 0, 0, .06);
  transform-origin: top center;
  opacity: 0;
  transform: scale(.96) translateY(-4px);
  pointer-events: none;
  transition: opacity .18s cubic-bezier(.4, 0, .2, 1),
              transform .26s cubic-bezier(.34, 1.56, .64, 1);
  overflow: hidden;
}
.asel-pop[data-dir="up"] { transform-origin: bottom center; }
.asel-pop.is-open {
  opacity: 1;
  transform: scale(1) translateY(0);
  pointer-events: auto;
}

/* 列表区（独立滚动，搜索框固定在上方） */
.asel-list {
  max-height: 264px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.asel-list::-webkit-scrollbar { width: 8px; }
.asel-list::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, .16);
  border-radius: 4px;
  border: 2px solid transparent;
  background-clip: content-box;
}
.asel-list::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, .28); background-clip: content-box; }

/* --- N4. 选项 --- */
.asel-opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  height: 36px;
  padding: 0 11px;
  margin: 1px 0;
  font-size: var(--fs-5);
  color: var(--ink);
  border-radius: 8px;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .12s;
}
.asel-opt-t {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.asel-opt:hover,
.asel-opt.hot { background: rgba(0, 113, 227, .10); }
.asel-opt[aria-selected="true"] {
  background: #0071E3;
  color: #fff;
}
.asel-opt[aria-selected="true"] .asel-tick { opacity: 1; }
.asel-opt[aria-disabled="true"] {
  color: var(--muted);
  cursor: not-allowed;
  background: transparent;
}

.asel-tick {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  opacity: 0;
  transition: opacity .12s;
}
.asel-tick svg { width: 100%; height: 100%; display: block; }

/* --- N5. 搜索框 / 分组标题 / 分隔线 --- */
.asel-search {
  display: block;
  width: 100%;
  height: 32px;
  margin: 2px 0 5px;
  padding: 0 10px;
  font: inherit;
  font-size: var(--fs-4);
  color: var(--ink);
  background: rgba(120, 120, 128, .10);
  border: 0;
  border-radius: 8px;
  outline: none;
}
.asel-search::placeholder { color: var(--muted); }
.asel-search:focus { background: rgba(120, 120, 128, .14); }

.asel-grp {
  padding: 9px 11px 5px;
  font-size: var(--fs-2);
  font-weight: 600;
  color: var(--muted);
  letter-spacing: .04em;
  text-transform: uppercase;
}

/* --- N6. 禁用态 --- */
.asel.is-disabled .asel-btn {
  background: var(--line-2);
  color: var(--muted);
  border-color: rgba(0, 0, 0, .06);
  box-shadow: none;
  cursor: not-allowed;
}
.asel.is-disabled .asel-btn:active { transform: none; }

/* --- N7. 特殊场景：原 select 宽度不是 100% 的地方 --- */
.toolbar .asel { width: auto; min-width: 136px; }
.tbl td > .asel { min-width: 0; }
.seg-tbl .asel { min-width: 74px; }
.seg-tbl .asel-btn { height: 32px; font-size: var(--fs-3); padding: 0 9px 0 10px; }

/* --- N8. 无障碍：减弱动效 --- */
@media (prefers-reduced-motion: reduce) {
  .asel-pop, .asel-btn, .asel-chev, .asel-opt, .asel-tick {
    transition-duration: .01ms !important;
  }
  .asel-pop { transform: none; }
  .asel-pop.is-open { transform: none; }
}

/* --- N9. 移动端不增强：若因断点变化残留了 wrapper，退回原生 --- */
@media (max-width: 767px) {
  .asel-btn, .asel-pop { display: none; }
  .asel > select.asel-native {
    position: static;
    opacity: 1;
    pointer-events: auto;
    z-index: auto;
    height: auto;
  }
}
