/* ============================================================
 * 助听器门店管理系统 - 后台管理端 全局统一样式 (VI / UI / 响应式)
 * 引入方式：每个页面 <head> 内 <title> 之后加一行
 *   <link rel="stylesheet" href="common.css?v=20260819">
 * 注意：本文件通过 Element Plus 原生 CSS 变量覆盖主题，
 *       业务页无需改动 el-* 组件即可自动跟随 VI 主色。
 * ============================================================ */

/* ---------- 1. 设计令牌（CSS 变量） ---------- */
:root {
  /* 品牌主色（VI 深蓝体系） */
  --ha-primary:        #1e3a5f;
  --ha-primary-light:  #2c5184;
  --ha-primary-dark:   #0d2137;
  --ha-primary-soft:   #eaf0f6;

  /* 功能色（统一明度，沿用 Element 语义） */
  --ha-success: #52c41a;
  --ha-warning: #faad14;
  --ha-danger:  #f5222d;
  --ha-info:    #8c8c8c;

  /* 中性色 */
  --ha-bg:        #f5f7fa;
  --ha-surface:   #ffffff;
  --ha-border:    #e8edf2;
  --ha-text:      #303133;
  --ha-text-sub:  #909399;
  --ha-text-weak: #c0c4cc;

  /* 侧边栏 */
  --ha-sider-bg-1: #1e3a5f;
  --ha-sider-bg-2: #0d2137;
  --ha-sider-text: rgba(255, 255, 255, 0.78);

  /* 圆角 / 阴影 / 间距 */
  --ha-radius:    8px;
  --ha-radius-lg: 12px;
  --ha-shadow:    0 2px 12px rgba(0, 0, 0, 0.05);
  --ha-shadow-h:  0 4px 20px rgba(0, 0, 0, 0.10);
  --ha-gap:       20px;

  /* 侧边栏宽度（受影响类引用，便于统一调整） */
  --ha-sider-w: 220px;
  --ha-sider-w-collapsed: 64px;

  /* ---------- Element Plus 主题覆盖：默认蓝 → VI 深蓝 ---------- */
  --el-color-primary:        #1e3a5f;
  --el-color-primary-light-3:#2c5184;
  --el-color-primary-light-5:#6b86a6;
  --el-color-primary-light-7:#aebfd2;
  --el-color-primary-light-8:#cdd8e5;
  --el-color-primary-light-9:#eaf0f6;
  --el-color-primary-dark-2: #0d2137;
  --el-border-radius-base:   8px;
}

/* ---------- 2. 基础重置 ---------- */
* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  font-family: 'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ha-text);
  background: var(--ha-bg);
}

/* 数字/金额等宽对齐 */
.ha-num, td.el-table__cell .cell { font-variant-numeric: tabular-nums; }

/* ---------- 3. 布局骨架 ---------- */

/* L1 全局壳层：统一「侧栏 + 内容区」结构，覆盖各页内联样式的差异。
   页面只需在 <body> 内使用 .app-container > .sidebar-container + .main-content 即可自动套壳。
   注意：.app-container 在众多业务页里被当作普通内容包装器使用，不要全局设 display:flex，
         避免把 .page-header/.stats-cards/.card 等块级子元素强压成 flex item 导致布局崩坏。 */
body > .app-container {
  display: flex;
  min-height: 100vh;
  background: var(--ha-bg);
}

/* 内容区（依赖变量，消除各页旧 260/220px 不一致）
   兼容两种写法：index 样板用 .ha-main，其余 76 页用 .main-content */
.ha-main,
.main-content {
  flex: 1;
  min-width: 0;                 /* 关键：允许内容区收缩，避免子级定宽把布局撑破 */
  margin-left: var(--ha-sider-w);
  padding: var(--ha-gap);
  min-height: 100vh;
  background: var(--ha-bg);
  box-sizing: border-box;
}

/* 页面头部卡片 */
.ha-page-header {
  background: var(--ha-surface);
  border-radius: var(--ha-radius-lg);
  padding: 20px 24px;
  margin-bottom: var(--ha-gap);
  box-shadow: var(--ha-shadow);
}
.ha-page-title { font-size: 20px; color: var(--ha-text); font-weight: 600; }
.ha-page-desc { font-size: 13px; color: var(--ha-text-sub); margin-top: 4px; }

/* 通用内容卡片 */
.ha-card {
  background: var(--ha-surface);
  border-radius: var(--ha-radius-lg);
  padding: 20px 24px;
  box-shadow: var(--ha-shadow);
  margin-bottom: var(--ha-gap);
}
.ha-card-title { font-size: 16px; font-weight: 600; color: var(--ha-text); margin-bottom: 16px; }

/* 统计卡片（兼容 index.html 的 stat-card 写法） */
.ha-stat-card, .stat-card {
  background: var(--ha-surface);
  border-radius: var(--ha-radius-lg);
  padding: 20px;
  box-shadow: var(--ha-shadow);
  transition: all 0.3s;
}
.ha-stat-card:hover, .stat-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--ha-shadow-h);
}
.ha-stat-card .icon, .stat-card .icon {
  width: 60px; height: 60px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 24px; color: #fff;
}
.ha-stat-card .value, .stat-card .value { font-size: 28px; font-weight: bold; color: var(--ha-text); margin: 10px 0; }
.ha-stat-card .label, .stat-card .label { font-size: 14px; color: var(--ha-text-sub); }

/* 统计卡图标配色（基于 VI 主色 + 功能色） */
.bg-primary   { background: var(--ha-primary) !important; }
.bg-success   { background: var(--ha-success) !important; }
.bg-warning   { background: var(--ha-warning) !important; }
.bg-danger    { background: var(--ha-danger) !important; }
.bg-info      { background: var(--ha-info) !important; }

/* ---------- 4. 侧边栏（覆盖 sidebar.js 注入的内联样式，统一用 VI 色） ---------- */
#sidebar-container {
  width: var(--ha-sider-w) !important;
  background: linear-gradient(180deg, var(--ha-sider-bg-1) 0%, var(--ha-sider-bg-2) 100%) !important;
}
/* 激活态改用 VI 主色高亮（原 #409eff 蓝） */
.sb-item.active, .sb-item.active-trail {
  background: rgba(30, 58, 95, 0.45) !important;
  border-left-color: var(--ha-primary-light) !important;
}
.sb-group-title.active-trail { color: #fff !important; }

/* 侧边栏图标与文字间距（emoji 替换 bi 后对齐） */
.sb-item-icon { width: 20px; text-align: center; flex-shrink: 0; }

/* 侧边栏快捷工具条（全部折叠 / 展开 / 搜索 / 定位） */
.sb-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 8px 10px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(0, 0, 0, 0.14);
}
.sb-tool-btn {
  flex: 1 1 0;
  min-width: 0;
  height: 30px;
  border: none;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.10);
  color: var(--ha-sider-text);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  line-height: 1;
  transition: background .15s, color .15s;
}
.sb-tool-btn:hover { background: rgba(255, 255, 255, 0.22); color: #fff; }
.sb-tool-btn:active { transform: translateY(1px); }
.sb-filter-input {
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: 6px 10px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.25);
  color: #fff;
  font-size: 13px;
  outline: none;
}
.sb-filter-input::placeholder { color: var(--ha-text-weak); }
.sb-filter-input:focus { border-color: var(--ha-primary-light); }
/* 定位当前页：黄色描边闪烁（用 outline 避免被 .active 的 !important 背景覆盖） */
.sb-locate-flash { animation: sb-locate-flash 1.6s ease; }
@keyframes sb-locate-flash {
  0%, 100% { outline: 2px solid transparent; outline-offset: -2px; }
  25%, 65% { outline: 2px solid var(--ha-warning); outline-offset: -2px; }
}

/* ---------- 统一快捷操作组件（js/quick-actions.js） ----------
   形态：L2 图标条（BI 图标 + tooltip，常驻不靠 hover，兼容触屏）
        + L3「更多」下拉（低频/危险操作）
   目的：操作列宽度固定，动作数量增加也不撑爆表格 */
.qa-root { display: inline-flex; align-items: center; gap: 2px; vertical-align: middle; }
.qa-icon-btn {
  border: none; background: transparent; color: var(--ha-primary);
  width: 28px; height: 28px; border-radius: 6px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 15px; line-height: 1; transition: background .15s, color .15s;
}
.qa-icon-btn:hover { background: var(--ha-primary-soft); color: var(--ha-primary-dark); }
.qa-more-wrap { position: relative; display: inline-flex; }
.qa-menu {
  position: absolute; right: 0; top: 100%; z-index: 2000;
  min-width: 132px; padding: 4px 0; margin-top: 4px;
  background: var(--ha-surface); border: 1px solid var(--ha-border);
  border-radius: var(--ha-radius); box-shadow: var(--ha-shadow-h);
}
.qa-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 12px; border: none; background: transparent;
  color: var(--ha-text); font-size: 13px; text-align: left;
  cursor: pointer; white-space: nowrap;
}
.qa-menu-item:hover { background: var(--ha-primary-soft); color: var(--ha-primary); }
.qa-menu-item i { font-size: 15px; }
/* 行右键菜单：按光标定位（left/top 由组件内联设置），不占列宽 */
.qa-menu--fixed { position: fixed; right: auto; top: 0; z-index: 4000; margin-top: 0; }

/* ---------- 详情抽屉内的快捷操作九宫格 ---------- */
.ha-qa-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.ha-qa-cell {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; padding: 12px 6px; border: 1px solid var(--ha-border);
  border-radius: var(--ha-radius); background: var(--ha-surface);
  color: var(--ha-text); cursor: pointer; font-size: 12px;
  transition: all .15s; text-decoration: none;
}
.ha-qa-cell i { font-size: 20px; color: var(--ha-primary); }
.ha-qa-cell:hover { border-color: var(--ha-primary); background: var(--ha-primary-soft); }
.ha-qa-section { margin-bottom: 14px; }
.ha-qa-title { font-size: 13px; font-weight: 600; color: var(--ha-text-sub); margin-bottom: 10px; }
@media (max-width: 767px) { .ha-qa-grid { grid-template-columns: repeat(3, 1fr); } }

/* 客户详情抽屉：强制块级布局；快捷操作为纵向列表（一排一个、通栏），
   描述信息单列展示，长值（如标签串）允许换行，标签列固定宽度不竖排 */
.ha-drawer-body {
  display: block;
  width: 100%;
  box-sizing: border-box;
  overflow-x: hidden; /* 防止任何内容横向溢出抽屉，画到抽屉外的页面上 */
}
/* 抽屉内容区垂直滚动：显式声明，防止全局样式覆盖 Element Plus 默认行为，
   保证内容再多也能用滚动条看完 */
.el-drawer__body { overflow-y: auto !important; }
/* 抽屉宽度：实测 size="600px" 未生效（渲染为默认 30%），用 CSS 强制；
   窄屏时不超窗 */
.el-drawer.customer-detail-drawer { width: 600px !important; max-width: 100vw; }
/* 快捷操作：顶部横向一排（放不下自动换行），小尺寸不占宽 */
.ha-qa-row { display: flex; flex-direction: row; flex-wrap: wrap; gap: 8px; }
.ha-qa-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 10px; border: 1px solid var(--ha-border);
  border-radius: 999px; background: var(--ha-surface);
  color: var(--ha-text); font-size: 12px; line-height: 1;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: all .15s;
}
.ha-qa-chip i { font-size: 13px; color: var(--ha-primary); }
.ha-qa-chip:hover { border-color: var(--ha-primary); background: var(--ha-primary-soft); color: var(--ha-primary); }
.ha-detail-desc { word-break: break-all; }
.ha-detail-desc .el-descriptions__label { width: 96px; white-space: nowrap; vertical-align: top; }
.ha-detail-desc .el-descriptions__content { word-break: break-all; }

/* 抽屉内信息分段：纯 HTML 键值行，不依赖 EP 表格语义，任何环境都按块级堆叠 */
.ha-sec {
  border: 1px solid var(--ha-border);
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 14px;
}
.ha-sec-title {
  padding: 8px 12px; font-size: 13px; font-weight: 600;
  color: var(--ha-text); background: #f7f8fa;
  border-bottom: 1px solid var(--ha-border);
}
.ha-kv { display: flex; align-items: flex-start; border-bottom: 1px solid var(--ha-border); }
.ha-kv:last-child { border-bottom: none; }
.ha-k {
  width: 110px; flex-shrink: 0; padding: 8px 10px;
  font-size: 12px; color: var(--ha-text-sub); background: #fafbfc;
  white-space: nowrap;
}
.ha-v {
  flex: 1; min-width: 0; padding: 8px 10px;
  font-size: 12px; color: var(--ha-text); word-break: break-all;
}

/* ---------- 5. 移动端顶部汉堡条（手机抽屉时显示） ---------- */
.ha-topbar {
  display: none;
  align-items: center;
  gap: 12px;
  position: sticky; top: 0; z-index: 1001;
  background: var(--ha-surface);
  padding: 12px 16px;
  box-shadow: var(--ha-shadow);
  margin: calc(var(--ha-gap) * -1) calc(var(--ha-gap) * -1) var(--ha-gap);
}
.ha-topbar .ha-burger {
  font-size: 22px; color: var(--ha-primary); cursor: pointer; line-height: 1;
}
.ha-topbar .ha-topbar-title { font-size: 16px; font-weight: 600; color: var(--ha-text); }

/* ---------- 6. 响应式 ---------- */

/* 平板：侧栏收成 64px 图标栏 */
@media (max-width: 1199px) {
  .ha-main,
  .main-content { margin-left: var(--ha-sider-w-collapsed) !important; padding: 16px; }
  #sidebar-container { width: var(--ha-sider-w-collapsed) !important; }
  #sidebar-container .sb-logo p,
  #sidebar-container .sb-group-title span:last-child,
  #sidebar-container .sb-item label,
  #sidebar-container .sb-item .sb-item-text { display: none; }
  #sidebar-container .sb-group-title,
  #sidebar-container .sb-item { justify-content: center; padding-left: 0 !important; padding-right: 0; }
  #sidebar-container .sb-logo { padding: 16px 0; text-align: center; }
  #sidebar-container .sb-logo h1 { font-size: 0; }
  #sidebar-container .sb-logo h1::first-letter { font-size: 18px; }
  #sidebar-container .sb-foot-name { display: none; }
  #sidebar-container .sb-footer { padding: 8px; }
  #sidebar-container .sb-foot-user { display: none; }
  #sidebar-container .sb-footer { justify-content: center; padding: 6px 4px; }
  #sidebar-container .sb-foot-actions { gap: 4px; }
  #sidebar-container .sb-foot-btn { width: 26px; height: 26px; font-size: 14px; }
}

/* 手机：侧栏转抽屉 + 顶部汉堡 */
@media (max-width: 767px) {
  .ha-main,
  .main-content { margin-left: 0 !important; padding: 12px; }
  #sidebar-container {
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    width: var(--ha-sider-w) !important;
    box-shadow: 2px 0 12px rgba(0,0,0,0.2);
    z-index: 1002;
  }
  body.sb-open #sidebar-container { transform: translateX(0); }
  body.sb-open::after {
    content: ''; position: fixed; inset: 0;
    background: rgba(0,0,0,0.35); z-index: 1001;
  }
  /* 抽屉展开时恢复侧栏内部完整显示 */
  body.sb-open #sidebar-container .sb-logo p,
  body.sb-open #sidebar-container .sb-user,
  body.sb-open #sidebar-container .sb-group-title span:last-child,
  body.sb-open #sidebar-container .sb-item .sb-item-text { display: revert; }
  body.sb-open #sidebar-container .sb-group-title,
  body.sb-open #sidebar-container .sb-item { justify-content: flex-start; padding-left: 20px !important; }
  body.sb-open #sidebar-container .sb-footer { display: flex; }

  .ha-topbar { display: flex; }
  /* 手机下卡片/表格允许横向滚动，避免挤压 */
  .ha-card, .ha-page-header { overflow-x: auto; }
  .el-table { width: 100%; overflow-x: auto; }
}

/* ============================================================
 * 7. 响应式护栏（防止不同分辨率下控件重合/溢出）
 *    后台 84 页多为内联定宽，无法逐页改；此处全局兜底。
 * ============================================================ */

/* 7.1 所有表格/数据区容器横向可滚动，避免宽表撑破布局 */
.el-table, .table-responsive, .ha-card table,
table.table { max-width: 100%; overflow-x: auto; }

/* 7.1b 列表/卡片中的图片一律按容器比例裁切填充，杜绝被拉伸变形。
   说明：后台列表缩略图多为固定宽高的 <img>，若不设 object-fit 会被压扁/拉长；
   真正的「要展示哪一块」由服务端派生（/api/image?...&fit=cover&fx=&fy=）围绕焦点决定。
   Logo 等需完整显示的图请用 .ha-img-contain 覆盖。 */
.el-table img, .table-responsive img,
.ha-card img, table.table img,
.ha-table-wrap img {
  object-fit: cover;
  object-position: center;
}
.ha-img-contain { object-fit: contain !important; }

/* 7.2 固定定位的打印层/遮罩必须给足够层级且不挡正常操作流 */
[style*="position: fixed"],
[style*="position:fixed"] {
  z-index: 2000 !important;
}

/* 7.3 内联定宽筛选框/输入：大屏保持，小屏改为自适应（限幅避免过宽） */
@media (max-width: 1199px) {
  [style*="width: 200px"],
  [style*="width:200px"],
  [style*="width: 220px"],
  [style*="width: 240px"] {
    width: 100% !important;
    max-width: 320px;
  }
}
@media (max-width: 767px) {
  [style*="width: 200px"],
  [style*="width:200px"],
  [style*="width: 220px"],
  [style*="width: 240px"],
  [style*="width: 260px"],
  [style*="width: 300px"] {
    width: 100% !important;
    max-width: 100%;
  }
}

/* 7.4 行内按钮组：nowrap 易在窄屏冲出，允许换行 */
.ha-btn-group,
[class*="btn-group"],
.d-flex[class*="btn"] {
  flex-wrap: wrap;
  gap: 8px;
}

/* 7.5 固定宽度的摘要/侧块（如 print-summary）：小屏改为整宽 */
@media (max-width: 767px) {
  [style*="width: 260px"],
  [style*="width:260px"] {
    width: 100% !important;
    margin-left: 0 !important;
  }
}

/* 7.6 弹窗在小屏不溢出视口 */
.modal-dialog {
  max-width: calc(100vw - 16px) !important;
  margin: 8px auto;
}
@media (max-width: 767px) {
  .modal { padding: 0 !important; }
  .modal-dialog { margin: 4px auto; }
  .modal-body { overflow-x: auto; }
}

/* 7.7 flex 容器内的子项在小屏允许收缩，避免溢出重叠
   （注意：仅作用于自定义 ha-* 容器，避免误伤 el-table 内部列的 min-width 机制导致其文字挤压重叠） */
.ha-main .ha-card *,
.ha-main .ha-page-header * {
  min-width: 0;
}

/* ============================================================
 * 8. L2 布局约定类（可选采纳）
 *    业务页逐步把内联定宽/手搓栅格替换为下列约定类，
 *    即可获得一致间距、对齐与响应式行为，无需重复写样式。
 * ============================================================ */

/* 8.1 筛选区：标签 + 控件横向排布，自动换行，窄屏整宽 */
.ha-filter-grid {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 16px;
  margin-bottom: var(--ha-gap);
}
.ha-filter-grid .ha-filter-item {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ha-filter-grid .ha-filter-item > label {
  white-space: nowrap;
  color: var(--ha-text-sub);
  font-size: 14px;
}
.ha-filter-grid .ha-filter-item > .el-input,
.ha-filter-grid .ha-filter-item > .el-select { width: 180px; }
.ha-filter-grid .ha-filter-item > .form-select,
.ha-filter-grid .ha-filter-item > .form-control { width: 180px; }

/* 兼容大量旧页未用 .ha-filter-item 包装的场景：
   直接子元素（无论 el-input / el-select / option-select / 其它自定义组件）
   默认固定 180px 并禁止收缩，按钮、文本标签保持自适应。
   用 > *:not(...) 避免依赖具体组件根 class 名；
   用 !important 覆盖 Element Plus 默认 width:100%（同优先级且后加载）。 */
.ha-filter-grid > *:not(.el-button):not(.el-button-group):not(label):not(.ha-filter-label):not(.ha-filter-item):not(.el-date-editor) {
  flex: 0 0 auto !important;
  width: 180px !important;
  max-width: 100%;
}
/* 日期范围选择器较宽，单独放宽；日期范围 "开始日期 至 结束日期" 需要 460px 才够舒展。
   关键：Element Plus 的 daterange 实际渲染根元素是
   `.el-date-editor.el-input__wrapper.el-date-editor--daterange`，
   其宽度由 Element 的 `.el-date-editor.el-input__wrapper { width: var(--el-date-editor-width) }`
   控制（默认 350px）。该规则特异性 (0,2,0) 与我们的普通规则平手，但因 Element CSS 后加载而胜出。
   因此这里直接命中 daterange 真实 class，特异性拉到 (0,5,0)，绝对压过 Element 默认 350px。 */
.ha-filter-grid .el-date-editor.el-input__wrapper.el-date-editor--daterange,
.ha-filter-grid .el-date-editor.el-input__wrapper.el-date-editor--datetimerange,
.ha-filter-grid .el-date-editor.el-input.el-date-editor--daterange,
.ha-filter-grid .el-date-editor.el-input.el-date-editor--datetimerange,
/* 兜底：只要带 daterange/datetimerange 类名的日期编辑器统一 460px，
   不依赖 Element UI / Element Plus 具体中间 class 名 */
.ha-filter-grid .el-date-editor.el-date-editor--daterange,
.ha-filter-grid .el-date-editor.el-date-editor--datetimerange,
.ha-filter-grid > .el-date-editor.el-date-editor--daterange,
.ha-filter-grid > .el-date-editor.el-date-editor--datetimerange {
  width: 460px !important;
  flex: 0 0 auto !important;
}

/* 8.1a 原生日期范围：用于非 Vue/Element 页面（如库存盘点） */
.ha-filter-grid .ha-date-range,
.ha-filter-grid .ha-filter-item > .ha-date-range {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: 320px !important;
  flex: 0 0 auto !important;
}
.ha-date-range > input[type="date"],
.ha-date-range > input[type="datetime-local"] {
  flex: 1 1 0;
  min-width: 0;
}
.ha-date-range .ha-date-range-sep {
  color: var(--ha-text-sub);
  white-space: nowrap;
  font-size: 14px;
}

@media (max-width: 767px) {
  .ha-filter-grid .ha-filter-item { width: 100%; }
  .ha-filter-grid .ha-filter-item > .el-input,
  .ha-filter-grid .ha-filter-item > .el-select { width: 100%; flex: 1; }

  /* 移动端直接子组件自动占满整行 */
  .ha-filter-grid > *:not(.el-button):not(.el-button-group):not(label):not(.ha-filter-label):not(.ha-filter-item):not(.el-date-editor) {
    width: 100% !important;
    flex: 1 1 100% !important;
  }
}

/* 8.2 操作按钮行：右对齐、可换行、统一间距 */
.ha-btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: var(--ha-gap);
}
.ha-btn-row.ha-btn-row--end { justify-content: flex-end; }
.ha-btn-row.ha-btn-row--between { justify-content: space-between; }
.ha-btn-row.ha-btn-row--center { justify-content: center; }

/* 8.3 表单网格：两/三列自适应，窄屏堆叠 */
.ha-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px 24px;
}
@media (max-width: 767px) {
  .ha-form-grid { grid-template-columns: 1fr; }
}

/* 8.4 表格横向滚动包裹：避免宽表把页面撑出 */
.ha-table-wrap {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.ha-table-wrap > .el-table { width: 100%; }

/* 8.5 卡片内区块标题（替代各页手搓 h3 + border） */
.ha-section-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--ha-text);
  margin: 4px 0 16px;
  padding-left: 10px;
  border-left: 3px solid var(--ha-primary);
  line-height: 1.3;
}

/* ============================================================
 * 9. L3 个别特例
 * ============================================================ */

/* 9.1 大屏 dashboard：保留深色风格，仅通过变量换主色，不套浅色壳。
   页面在 <body> 上加 .ha-dark 即可启用。侧栏让位沿用通用 .main-content
   规则（margin-left:var(--ha-sider-w)），此处只接管深色背景/文字，
   不再覆盖 margin-left，避免内容被固定侧栏遮挡。 */
body.ha-dark,
body.ha-dark .main-content {
  background: #0d2137;            /* 沿用 VI 深蓝底，替换原 #1e3a5f 渐变 */
  color: rgba(255,255,255,0.85);
}
body.ha-dark .ha-card,
body.ha-dark .ha-page-header,
body.ha-dark .el-card {
  background: rgba(255,255,255,0.04);
  color: rgba(255,255,255,0.9);
  border: 1px solid rgba(255,255,255,0.08);
  box-shadow: none;
}
body.ha-dark .el-table,
body.ha-dark .el-table tr,
body.ha-dark .el-table th {
  background: transparent;
  color: rgba(255,255,255,0.85);
}
body.ha-dark .el-table td,
body.ha-dark .el-table th.is-leaf {
  border-bottom-color: rgba(255,255,255,0.08);
}

/* 9.2 修改密码等独立居中页：手机上容器自适应不溢出（不套壳、保留其登录式布局） */
@media (max-width: 767px) {
  .container { width: 92vw !important; max-width: 420px; }
}

/* 10. AI 参与标识
   用途：标记「有大语言模型参与生成内容」的按钮 / 入口，让用户在点击前就知道产出由 AI 生成。
   约定：只用于 AI 实际产出内容的入口；纯 AI 配置（保存配置、新增触发词等）不打标，
         否则满屏都是标识会使其失去意义。
   实现：纯 CSS 渐变胶囊，不引入新的图标字体或图片资源，全站复用同一类名。 */
.ai-badge {
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-right: 4px;
  vertical-align: middle;
  /* 蓝底圆角方块 + 白色 A + 浅蓝 I（图标自带文字，故元素内不再写 "AI"）。
     base64 内联：管理端无图片资源目录，内联可避免新增文件与静态资源路径风险。 */
  background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHZpZXdCb3g9JzAgMCAxMDI0IDEwMjQnPjxwYXRoIGQ9J004MTYuNDIzNjE5OTUgOTM1Ljc2NzEwMzJIMjA4LjY1MDg0NjgyYy02Ni4yMTU2MzI1OSAwLTExOS44ODcxODkzMy01My42NzE1NTY3NS0xMTkuODg3MTg5MzQtMTE5Ljg4NzE4OTMzVjIwOC4xMjAwODYxM2MwLTY2LjIxNTYzMjU5IDUzLjY3MTU1Njc1LTExOS44ODcxODkzMyAxMTkuODg3MTg5MzQtMTE5Ljg4NzE4OTMzaDYwNy43NzI3NzMxM2M2Ni4yMTU2MzI1OSAwIDExOS44ODcxODkzMyA1My42NzE1NTY3NSAxMTkuODg3MTg5MzMgMTE5Ljg4NzE4OTMzdjYwNy43NzI3NzMxMmMwIDY2LjIwMjY4NzItNTMuNjcxNTU2NzUgMTE5Ljg3NDI0Mzk1LTExOS44ODcxODkzMyAxMTkuODc0MjQzOTV6JyBmaWxsPScjMEU4Q0ZCJy8+PHBhdGggZD0nTTU1Mi44Mjk3MzcwOSAzNTcuOTExMTA5NTNsNDEuMzg2Mzg4NTQgMzA4LjE5MDcyNjMyaC05My42MzM5NTMxOGwtMTAuOTAwMDEyMjYtODMuODg2MDhIMzU5LjAxMTQ2NzA2bC0zNi41MTg5MjQ2NCA4My44ODYwOGgtODguNzUzNTQzOWwxMjAuMzUzMjIzMTEtMjkyLjk0MTA2NTQ4LTE1Ljc4MDQyMTUzLTE1LjIzNjcxNTQ2aDIxNC41MTc5MzY5OXogbS0xMjAuMzAxNDQxNTkgNTIuMjM0NjE5MjdsLTUyLjI4NjQwMDc4IDExOS44MjI0NjI0aDEwNC41MzM5NjU0M2wtMTUuNzgwNDIxNTQtMTE5LjgyMjQ2MjRoLTM2LjQ2NzE0MzExeicgZmlsbD0nI0ZGRkZGRicvPjxwYXRoIGQ9J003OTEuMzA5NTc3NDggMzU3LjkxMTEwOTUzbC00Ny4zNjcxNTUzNSAzMDguMTkwNzI2MzJINjQ0LjgxOTYyNjY3bDM2LjUxODkyNDY0LTI4Ny40OTEwNTkzNS0xNS44MTkyNTc2OC0yMC42OTk2NjY5N2gxMjUuNzkwMjgzODV6JyBmaWxsPScjQzZFNUY3Jy8+PC9zdmc+");
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  user-select: none;
  cursor: default;
}
