
/* ===== qihui-modal.css (modal base + variables) ===== */
/* =========================================================
   启慧模态框统一规范  (qihui-modal.css)
   ---------------------------------------------------------
   统一目标：
   1) 标题固定左上角，关闭按钮(×)固定右上角；
   2) 内容字号 = --qihui-modal-content-font-size
      （与教育诊断模态框一致，默认 15px）；
   3) 标题字号 = 内容字号 × 1.2，修改内容字号时标题自动跟随。

   所有模态框（含 .qm-modal、各业务页 modal）均继承此规范。
   仅需修改本文件 :root 中的变量，即可全局生效（一处修改，全站适用）。
   ========================================================= */
:root {
    /* 内容字号：与教育诊断模态框保持一致 */
    --qihui-modal-content-font-size: 15px;
    /* 标题字号：内容字号的 1.2 倍（修改内容字号会自动联动） */
    --qihui-modal-title-font-size: calc(var(--qihui-modal-content-font-size) * 1.2);
}

/* 模态框头部：相对定位，作为关闭按钮绝对定位的基准 */
.modal .modal-header {
    position: relative;
}

/* 标题：固定左上角，统一字号与字重 */
.modal .modal-title {
    font-size: var(--qihui-modal-title-font-size);
    font-weight: 600;
    margin: 0;
    /* 预留右侧空间，避免长标题与右上角关闭按钮重叠 */
    padding-right: 2.5rem;
}
/* 标题内若嵌套 <label>（部分 JS 动态拼接的标题），
   继承标题字号，避免被全局 label 规则缩成 .85rem */
.modal .modal-title label {
    font-size: inherit !important;
    font-weight: inherit !important;
    margin: 0;
}

/* 关闭按钮：固定右上角，垂直居中 */
.modal .modal-header .btn-close {
    position: absolute;
    right: 1rem;
    top: 50%;
    transform: translateY(-50%);
    margin: 0;
}

/* 内容区：统一字号，与教育诊断模态框一致 */
.modal .modal-body {
    font-size: var(--qihui-modal-content-font-size);
}



/* ===== iep/_qihui_modal.html (.qm-modal) ===== */
/* ======== 统一模态框美化样式 ======== */
/* 提示/确认消息模态框始终在最上层，不被其他模态框遮挡 */
#qm_message_modal,
#qm_confirm_modal {
    z-index: 99999;
}
.qm-modal .modal-content {
    border-radius: 8px;
    box-shadow: 0 10px 40px rgba(0,0,0,0.2);
    border: none;
    overflow: hidden;
}
.qm-modal .modal-header {
    padding: 16px 24px 12px;
    border-bottom: 1px solid #f0f0f0;
    display: flex;
    align-items: center;
    gap: 10px;
    position: relative;
}
.qm-modal .modal-header .btn-close {
    position: absolute;
    right: 24px;
    top: 50%;
    transform: translateY(-50%);
    margin: 0;
}
.qm-modal .modal-header .qm-icon {
    width: 32px; height: 32px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 16px; flex-shrink: 0;
}
.qm-modal .modal-header .qm-icon.success { background: #e6f7e6; color: #52c41a; }
.qm-modal .modal-header .qm-icon.error   { background: #fff1f0; color: #ff4d4f; }
.qm-modal .modal-header .qm-icon.warning { background: #fff7e6; color: #fa8c16; }
.qm-modal .modal-header .qm-icon.info    { background: #e6f7ff; color: var(--qihui-primary); }
.qm-modal .modal-header .qm-icon.confirm { background: #fff7e6; color: #fa8c16; }
.qm-modal .modal-title {
    font-size: var(--qihui-modal-title-font-size);
    font-weight: 600;
    line-height: 1.4;
    margin: 0;
}
.qm-modal .modal-body {
    padding: 20px 24px;
    font-size: var(--qihui-modal-content-font-size);
    color: #555;
    line-height: 1.7;
}
.qm-modal .modal-body strong { color: #333; }
.qm-modal .modal-body .qm-detail {
    margin-top: 12px;
    padding: 10px 14px;
    background: #fafafa;
    border-radius: 4px;
    border-left: 3px solid var(--qihui-primary);
    font-size: 13px;
    color: #666;
}
.qm-modal .modal-footer {
    padding: 12px 24px 16px;
    border-top: 1px solid #f0f0f0;
    text-align: right;
}
.qm-modal .modal-footer .btn {
    min-width: 72px;
    border-radius: 4px;
    padding: 6px 18px;
    font-size: 14px;
}
.qm-modal .modal-footer .btn-qm-primary {
    background: var(--qihui-btn-primary-bg);
    color: #fff;
    border-color: var(--qihui-btn-primary-bg);
}
.qm-modal .modal-footer .btn-qm-primary:hover { background: var(--qihui-btn-primary-hover-bg); border-color: var(--qihui-btn-primary-hover-bg); }
.qm-modal .modal-footer .btn-qm-danger {
    background: var(--qihui-btn-danger-bg);
    color: #fff;
    border-color: var(--qihui-btn-danger-bg);
}
.qm-modal .modal-footer .btn-qm-danger:hover { background: var(--qihui-btn-danger-hover-bg); border-color: var(--qihui-btn-danger-hover-bg); }
.qm-modal .modal-footer .btn-qm-warning {
    background: var(--qihui-btn-warning-bg);
    color: #fff;
    border-color: var(--qihui-btn-warning-bg);
}
.qm-modal .modal-footer .btn-qm-warning:hover { background: var(--qihui-btn-warning-hover-bg); border-color: var(--qihui-btn-warning-hover-bg); }

/* 目标编辑模态框 */
.qm-modal .qm-form-group {
    margin-bottom: 14px;
    display: flex;
    flex-wrap: wrap;
}
.qm-modal .qm-form-group label {
    width: 90px;
    padding-top: 6px;
    font-weight: 600;
    color: #333;
    font-size: 13px;
    text-align: left;
    padding-right: 10px;
}
.qm-modal .qm-form-group .qm-form-control {
    flex: 1;
    min-width: 200px;
}
.qm-modal .qm-form-group .qm-form-control input,
.qm-modal .qm-form-group .qm-form-control select,
.qm-modal .qm-form-group .qm-form-control textarea {
    width: 100%;
    padding: 6px 10px;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    font-size: 13px;
    transition: border-color .3s, box-shadow .3s;
}
.qm-modal .qm-form-group .qm-form-control input:focus,
.qm-modal .qm-form-group .qm-form-control select:focus,
.qm-modal .qm-form-group .qm-form-control textarea:focus {
    border-color: var(--qihui-primary);
    box-shadow: 0 0 0 2px rgba(24,144,255,0.15);
    outline: none;
}
.qm-modal .qm-form-group .qm-form-control textarea {
    resize: vertical;
    min-height: 60px;
}
.qm-modal .qm-form-short label {
    width: 60px;
}
.qm-modal .qm-form-group .qm-form-control .form-text {
    display: block;
    padding: 6px 0;
    color: #555;
    font-size: 13px;
}
.qm-modal .qm-error {
    color: #ff4d4f;
    font-size: 12px;
    margin-top: 4px;
    display: none;
}
.qm-modal .qm-section-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--qihui-primary);
    margin: 18px 0 12px;
    padding-bottom: 6px;
    border-bottom: 1px dashed #e8e8e8;
}
/* 基本信息同行布局 */
.qm-modal .qm-form-row {
    display: flex;
    flex-wrap: wrap;
    margin-bottom: 14px;
    gap: 16px;
}
.qm-modal .qm-form-inline {
    display: flex;
    flex: 1;
    min-width: 160px;
}
.qm-modal .qm-form-inline label {
    width: 60px;
    padding-top: 6px;
    font-weight: 600;
    color: #333;
    font-size: 13px;
    text-align: left;
    padding-right: 8px;
    flex-shrink: 0;
}
.qm-modal .qm-form-inline .qm-form-control {
    flex: 1;
    min-width: 60px;
}
.qm-modal .qm-form-inline .qm-form-control input,
.qm-modal .qm-form-inline .qm-form-control select,
.qm-modal .qm-form-inline .qm-form-control textarea {
    width: 100%;
    padding: 6px 10px;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
    font-size: 13px;
    transition: border-color .3s, box-shadow .3s;
}
.qm-modal .qm-form-inline .qm-form-control .form-text {
    display: block;
    padding: 6px 0;
    color: #555;
    font-size: 13px;
}

/* ===== templates/header.html (navbar / dropdown / wechat / badge) ===== */
/* 待办红色角标：BS5 无对应组件，保留自定义 */
.badge-pending-nav {
  display:inline-block; min-width:18px; height:18px; line-height:18px;
  padding:0 5px; font-size:11px; font-weight:700; color:#fff;
  background:#e05050; border-radius:9px; text-align:center;
  vertical-align:middle; box-shadow:0 1px 3px rgba(0,0,0,.2);
}
.navbar-nav .dropdown-menu .badge-pending-nav { margin-top:-1px; }

/* 品牌字号：略大于导航，形成层级对比，不加粗 */
.navbar-dark .navbar-brand { font-size:1.05rem; font-weight:400; }

/* 顶部导航栏主色 / 内边距 / 阴影 / 与品牌 logo 尺寸：
   原写在 header.html 的内联 style= 上，但部分环境（生产 nginx/uWSGI 另加的更严格
   CSP 移除 style-src 的 'unsafe-inline'）会拦截内联 style=，导致背景丢失、logo 变大。
   改为外部 CSS（'self' 样式表不受 style-src 限制），dev / 生产均稳定生效。 */
.qihui-navbar {
  background-color:#4a7fb5;
  padding:0 30px;
  margin-bottom:20px;
  box-shadow:0 2px 10px rgba(0,0,0,.15);
}
.qihui-navbar .navbar-brand img {
  width:30px;
  height:30px;
  margin-right:8px;
}

/* 导航链接：更高（加高导航栏）/ 字更亮 / 字号更小 / 横向间距更大 */
.navbar-dark .navbar-nav .nav-link {
  position:relative;
  padding-top:1rem; padding-bottom:1rem;
  padding-left:.9rem; padding-right:.9rem;
  font-size:.85rem; line-height:1.2;
  color:#fff;
  border-radius:6px;
  transition:color .18s ease, background-color .18s ease, transform .18s ease;
}
/* 悬浮灵动：背景高亮 + 轻微上浮 + 底部指示条（仅非下拉项，避免覆盖 caret） */
.navbar-dark .navbar-nav .nav-link:not(.dropdown-toggle)::after {
  content:"";
  position:absolute;
  left:.9rem; right:.9rem; bottom:.55rem;
  height:2px; border-radius:2px;
  background:#fff;
  transform:scaleX(0);
  transform-origin:center;
  transition:transform .18s ease;
}
.navbar-dark .navbar-nav .nav-link:hover,
.navbar-dark .navbar-nav .nav-link:focus,
.navbar-dark .navbar-nav .nav-link.show {
  color:#fff;
  background-color:rgba(255,255,255,.15);
  transform:translateY(-2px);
}
.navbar-dark .navbar-nav .nav-link:not(.dropdown-toggle):hover::after,
.navbar-dark .navbar-nav .nav-link:not(.dropdown-toggle):focus::after,
.navbar-dark .navbar-nav .nav-link:not(.dropdown-toggle).show::after { transform:scaleX(1); }

/* 下拉菜单：无边框 + 轻量阴影 + 淡入上滑动画 */
.dropdown-menu {
  border:none;
  box-shadow:0 6px 20px rgba(0,0,0,.15);
  animation:dq-menu-in .16s ease;
}
@keyframes dq-menu-in {
  from { opacity:0; transform:translateY(-6px); }
  to   { opacity:1; transform:translateY(0); }
}

/* 操作下拉菜单 — 纯 opacity 淡入，避免 transform 与 Popper 定位冲突
   全局 .dropdown-menu 的 dq-menu-in 动画含 transform:translateY(-6px)，
   会与 Popper 的 translate3d 定位冲突 → 下拉先闪现到按钮上方再跳回下方。
   此处用纯 opacity 动画覆盖，不干扰 Popper 定位。 */
.op-dropdown {
  border-radius:6px;
  padding:8px 0;
  margin-top:6px;
  min-width:140px;
  animation: opFadeIn .15s ease;
}
@keyframes opFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.op-dropdown .divider {
  margin:4px 0; height:0; overflow:hidden;
  border-top:1px solid #e5e5e5; list-style:none;
}

/* 操作下拉各项颜色（原先各页面内联重复，现提取到全局） */
.op-item-add  { color:#31708f; }
.op-item-add:hover  { background-color:#f0f4f8; color:#245269; }
.op-item-edit { color:#f0ad4e; }
.op-item-edit:hover { background-color:#fef9f0; color:#ec971f; }
.op-item-delete { color:#d9534f; }
.op-item-delete:hover { background-color:#fdf7f7; color:#c9302c; }
.op-item-copy { color:#5bc0de; }
.op-item-copy:hover { background-color:#f2f9fc; color:#46b8da; }
.op-item-create { color:#5cb85c; }
.op-item-create:hover { background-color:#f0f9f0; color:#4cae4c; }
.op-item-export { color:#777; }
.op-item-export:hover { background-color:#f5f5f5; color:#555; }
.op-item-family { color:#8e44ad; }
.op-item-family:hover { background-color:#f9f0fc; color:#7d3c98; }

/* 下拉项：字号与导航一致，加大内边距让选项间距更大，悬浮文字右移 + 配色，更灵动（无左侧竖条） */
.dropdown-item {
  font-size:.85rem;
  padding-top:.55rem; padding-bottom:.55rem;
  padding-left:1.2rem; padding-right:1.2rem;
  transition:background-color .15s ease, color .15s ease, padding-left .15s ease;
}
.dropdown-item:hover,
.dropdown-item:focus {
  background-color:#f0f4f8;
  color:#4a7fb5;
  padding-left:1.7rem;
}
/* ===== 模态框全局最小宽度 ===== */
.modal-dialog {
    min-width: 480px;
}

/* 全显模式密码模态框样式 */
#fullDisplayModal .modal-dialog { max-width:420px; }
#fullDisplayModal .modal-body { padding:20px 24px; }

/* 微信绑定扫码弹窗样式 */
.wechat-qr-overlay {
	display:none; position:fixed; top:0;left:0;width:100%;height:100%;
	background:rgba(0,0,0,.5); z-index:999999;
}
.wechat-qr-overlay.show { display:block; }
.wechat-qr-modal {
	position:absolute; top:50%;left:50%;transform:translate(-50%,-50%);
	background:#fff; border-radius:12px; padding:28px; width:300px; text-align:center;
	box-shadow:0 16px 48px rgba(0,0,0,.25);
}
.wechat-qr-modal h4 { margin:0 0 16px; color:#333; font-size:16px; }
.wechat-qr-box {
	width:180px; height:180px; margin:0 auto 14px; border:1px solid #eee;
	border-radius:8px; display:flex; align-items:center; justify-content:center;
	background:#fafafa; overflow:hidden;
}
.wechat-qr-box img { width:100%; height:100%; object-fit:contain; }
.wechat-qr-placeholder { color:#999; font-size:13px; }
.wechat-qr-spinner {
	width:28px; height:28px; border:3px solid #e0e0e0; border-top-color:#07c160;
	border-radius:50%; animation:wechat-qr-spin .8s linear infinite; margin:0 auto 10px;
}
@keyframes wechat-qr-spin { to { transform:rotate(360deg); } }
.wechat-qr-status { font-size:13px; margin-bottom:12px; }
.wechat-qr-status.pending { color:#666; }
.wechat-qr-status.scanned { color:#ff9800; }
.wechat-qr-status.completed { color:#07c160; }
.wechat-qr-status.expired { color:#f44336; }
.wechat-qr-btn { width:100%; padding:8px; border:none; border-radius:6px; font-size:13px; cursor:pointer; margin-bottom:6px; }
.wechat-qr-btn-retry { background:#07c160; color:#fff; }
.wechat-qr-btn-retry:hover { background:#06ad56; }
.wechat-qr-btn-close { background:#f5f5f5; color:#666; }
.wechat-qr-btn-close:hover { background:#e0e0e0; }
.wechat-qr-error { color:#f44336; font-size:12px; margin-top:6px; }

/* 解绑微信确认模态框 */
#unbindWechatModal .modal-dialog { max-width:400px; }
#unbindWechatModal .modal-body { padding:20px 24px; }

/* ===== iep/_loading_overlay.html (#batch_loading_overlay) ===== */
#batch_loading_overlay {
        display: none !important;
        position: fixed;
        z-index: 999999;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background: rgba(0,0,0,0.55);
        isolation: isolate;
    }
    #batch_loading_overlay .logo-spin {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        width: 200px;
        height: 130px;
        animation-name: iepPulse;
        animation-duration: 1.6s;
        animation-timing-function: ease-in-out;
        animation-iteration-count: infinite;
    }
    @keyframes iepPulse {
        0%, 100% { opacity: 0.55; }
        50%      { opacity: 1; }
    }
    /* 显隐走类（替代 jQuery fadeIn/fadeOut 内联 style，兼容严格 CSP） */
    #batch_loading_overlay.is-visible { display: block !important; }

/* ===== IEP 详情页头部：左标签自适应占满 + 右控件靠右 =====
   原本布局写在模板内联 style= 上，生产端严格 CSP 会拦截 inline-style，
   导致子元素 flex 失效、下拉框/操作按钮回到左侧。改为外部 CSS（'self' 不受 style-src 限制）。 */
.iep-head-row {
  display: flex;
  align-items: flex-end;
  margin-bottom: 10px;
  border-bottom: 2px solid #e3e8ee;
}
.iep-head-row .tabs-col {
  flex: 1 1 auto;
  min-width: 0;
}
.iep-head-row .ctrls-col {
  flex: 0 0 auto;
  padding-bottom: 6px;
  text-align: right;
  white-space: nowrap;
}
/* 课程评估页控件区：内部横向排列并整体靠右 */
.iep-head-row .ctrls-col.is-flex {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 6px;
}
/* 标签导航行统一底线：移除 nav-tabs-lively 自身的底部边框，
   让 .iep-head-row 的 border-bottom 成为整行唯一贯穿的线条 */
.iep-head-row .nav-tabs-lively {
  border-bottom: none !important;
  margin-bottom: 0 !important;
}

/* ===== 全局轻量 toast 提示 =====
   取代原先内联 style 的 $('<div style="top:70px;left:50%;...">')（生产 CSP 会拦截内联 style，
   导致提示框无定位/无背景）。全部视觉走外部类，符合严格 CSP。 */
.qihui-toast {
    position: fixed;
    top: 70px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 99999;
    height: 42px;
    line-height: 22px;
    padding: 10px 24px;
    border-radius: 4px;
    font-size: 15px;
    color: #fff;
    box-shadow: 0 4px 12px rgba(0, 0, 0, .3);
    opacity: 0;
    transition: opacity .4s;
    pointer-events: none;
    white-space: nowrap;
    max-width: 90vw;
    overflow: hidden;
    text-overflow: ellipsis;
}
.qihui-toast--show { opacity: 1; }
.qihui-toast--success { background: #5cb85c; }
.qihui-toast--warning { background: #f0ad4e; }
.qihui-toast--danger  { background: #d9534f; }
.qihui-toast--error   { background: #d9534f; }
.qihui-toast--info    { background: #5bc0de; }

/* 全局 showAlert 的兜底容器（仅当页面无 #alertBox 时由 JS 自动创建）
   定位参照"发展评估 - 批量新增/编辑"页 .header-alert：
   导航下方 80px、水平居中、不挡标题卡片与关键信息 */
.qihui-alert-fixed {
  position: fixed;
  top: 80px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1080;
  min-width: 280px;
  max-width: 600px;
  text-align: center;
  box-shadow: 0 4px 16px rgba(0,0,0,0.18);
  display: none;
  opacity: 0;
  transition: opacity .25s ease;
}
/* 显隐走类（替代 jQuery fadeIn/fadeOut 内联 style，兼容严格 CSP） */
.qihui-alert-fixed.qihui-alert--show { display: block !important; opacity: 1; }

/* 下拉无数据选项的灰显（替代原先 .css('color') 内联样式，兼容严格 CSP） */
.is-unavailable { color: #aaa !important; }

/* SVG 进度环：原先 <svg style="top:0;left:0;"> 违反严格 CSP，改为类定位 */
.circle-svg { top: 0; left: 0; }

/* 列表操作图标：原先 <span style="width:15%"> 违反严格 CSP，改为类 */
.op-icon { width: 15%; }

/* ===== AI 分析模态框「生成中」覆盖式遮罩 =====
   覆盖整个 modal-body，半透明背景 + 居中提示，明确"可关闭窗口"。
   显隐走 .d-none（兼容严格 CSP，绝不写内联 style）。 */
.ai-mask {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.82);
  border-radius: 4px;
  text-align: center;
  padding: 1.5rem;
}
.ai-mask__box { max-width: 360px; }
.ai-mask__tip { margin: 1rem 0 0.5rem; font-weight: 600; color: #333; }
.ai-mask__sub { margin: 0; font-size: 0.875rem; color: #6c757d; }
/* 四好模板遮罩使用 .ai-analyze-mask，复用同样的子元素样式，保证双模块一致 */
.ai-analyze-mask .ai-mask__tip { margin: 1rem 0 0.5rem; font-weight: 600; color: #333; }
.ai-analyze-mask .ai-mask__sub { margin: 0; font-size: 0.875rem; color: #6c757d; }
/* 遮罩绝对定位需要 modal-body 作为参照系 */
@media (min-width: 1px) { #aiAnalysisModal .modal-body { position: relative; } }

/* ===== AI 分析启动提示：复用项目统一 .qm-modal 交互式模态框样式 =====
   视觉（圆角、阴影、标题栏、info 图标、主色按钮）与 confirmModal / QihuiModal 完全一致，
   仅在此限制宽度并居中。显隐由 Bootstrap .modal('show'/'hide') 驱动（生成 .modal-backdrop
   蒙层），无任何内联 style，符合严格 CSP。 */
.qihui-ai-modal {
    max-width: 440px;
    margin: 1.75rem auto;
}
#qihuiAiNotice .modal-body { text-align: left; }
/* 评估列表操作列 / 复选框标签：原先内联 style，改为类 */
.cell-nowrap { white-space: nowrap; }
.op-label { margin-right: 12px; }

/* ===== 全局表格统一美化（极简单线风格）=====
   此段必须在 Bootstrap 之后加载才能覆盖 BS5 默认表格样式。
   border-collapse:separate + border-radius 实现圆角；为保持单线观感，
   单元格仅保留右下边框（上/左边框由前一行/前一列提供），避免相邻边框叠加。 */
.table {
	--bs-table-hover-bg: #eef4fb;
	--bs-table-striped-bg: transparent;
	--bs-table-border-color: #ddd;
	color: #333;
	border-collapse: separate;
	border-spacing: 0;
	border: 1px solid #ddd;
	border-radius: 6px;
}
/* 圆角裁切：overflow:hidden 让圆角干净裁切单元格背景。
   排除 .batch-edit-table（含 position:sticky，overflow:hidden 会破坏 sticky），
   该类表由下方四角单元格圆角规则兜底。 */
.table:not(.batch-edit-table) { overflow: hidden; }
/* 单元格：右下边框（左+上由相邻格提供），消除双线 */
.table > :not(caption) > * > * {
	padding: .55rem .75rem;
	vertical-align: middle;
	border-width: 0 1px 1px 0;
	border-style: solid;
	border-color: #ddd;
}
/* 补回首行顶边 + 首列左边 */
.table > * > tr:first-child > * { border-top-width: 1px; }
.table > * > tr > :first-child { border-left-width: 1px; }
/* 表头（thead th）：浅灰底、深灰加粗、统一左对齐 */
table.table thead > tr > th,
table thead > tr > th {
	background-color: #f8f9fa;
	color: #555 !important;
	font-weight: 600;
	vertical-align: middle;
	text-align: left !important;
	white-space: nowrap;
}
/* 表头高度统一：覆盖 .table-sm 的表头压缩 */
.table thead th {
	padding-top: .55rem;
	padding-bottom: .55rem;
}
/* 行悬停：淡蓝高亮 */
.table > tbody > tr:hover > * {
	background-color: var(--bs-table-hover-bg, #eef4fb);
}
/* 四角单元格圆角：针对 .batch-edit-table（无 overflow:hidden）单独处理 */
.table > thead > tr:first-child > *:first-child { border-top-left-radius: 6px; }
.table > thead > tr:first-child > *:last-child  { border-top-right-radius: 6px; }
.table > tbody > tr:last-child  > *:first-child { border-bottom-left-radius: 6px; }
.table > tbody > tr:last-child  > *:last-child  { border-bottom-right-radius: 6px; }
.table > tbody > tr:only-child > *:first-child { border-top-left-radius: 6px; border-bottom-left-radius: 6px; }
.table > tbody > tr:only-child > *:last-child  { border-top-right-radius: 6px; border-bottom-right-radius: 6px; }
/* ===== 表格样式结束 ===== */

/* ===== 统一删除/确认弹窗宽度 =====
   全站所有删除确认模态框统一宽度 480px（含通用 confirmModal、
   各页面自建删除框）。走外部 class，避免内联 style 触发 CSP。 */
.qihui-confirm-modal { max-width: 480px; }
.qihui-del-modal { max-width: 480px; }

/* ===== 批量评估页：拖动学生列头移动整列（column-reorder.js）=====
   视觉反馈全部走外部 class，不注入内联 style，符合严格 CSP。 */
.batch-edit-table thead th.col-student { cursor: grab; -webkit-user-select: none; user-select: none; }
.batch-edit-table thead th.col-student:active { cursor: grabbing; }
/* 拖动中：被拖列半透明 */
.batch-edit-table thead th.col-student.col-dragging { opacity: .5; }
/* 落点指示：目标列左侧/右侧细蓝线（inset box-shadow，不触发 CSP） */
.batch-edit-table thead th.col-student.col-drop-before { box-shadow: inset 3px 0 0 0 #4a7fb5; }
.batch-edit-table thead th.col-student.col-drop-after  { box-shadow: inset -3px 0 0 0 #4a7fb5; }

/* ===== 统一分页栏（左分页按钮 / 右每页显示+页信息，对齐目标制定与检核页）=====
   作用域限定 .qihui-pagination*，不改动全局 .pagination，避免影响 modal 内分页等其它位置。
   字号统一 .875rem，激活态用顶部导航栏品牌蓝（--qihui-primary，#4a7fb5），更柔和协调、不刺眼。 */
.qihui-pagination .page-link {
  font-size: .875rem;
  padding: .25rem .5rem;
  line-height: 1.4;
}
/* 右侧信息区与下拉字号与分页按钮一致 */
.qihui-pagination-info,
.qihui-pagination-info label,
.qihui-pagination-info span,
.qihui-pagination-info .form-select {
  font-size: .875rem;
}
/* 下拉与按钮同行、宽度自适应内容、高度协调 */
.qihui-pagination-info .form-select {
  padding-top: .25rem;
  padding-bottom: .25rem;
}
/* 激活页：品牌蓝底白字（替代 Bootstrap 默认 --bs-primary 的鲜艳蓝） */
.qihui-pagination .page-item.active .page-link {
  background-color: var(--qihui-primary);
  border-color: var(--qihui-primary);
  color: #fff;
}
.qihui-pagination .page-item.active .page-link:hover {
  background-color: var(--qihui-primary-hover);
  border-color: var(--qihui-primary-hover);
}
/* 键盘焦点：品牌蓝描边，无内联 style，符合严格 CSP */
.qihui-pagination .page-link:focus {
  box-shadow: 0 0 0 .2rem rgba(74, 127, 181, .25);
}

/* ===== 全局"操作"下拉菜单样式（单一可信源 / Single Source of Truth）=====
   原散落在 9 个模板的内联 <style>，现统一抽取至此，实现"一处修改、全局一致"。
   纯 opacity 淡入，避免 transform 与 Bootstrap5 Popper 定位冲突。 */
.op-dropdown {
	border-radius:6px;
	padding:8px 0;
	margin-top:6px;
	min-width:140px;
	animation: opFadeIn .15s ease;
}
@keyframes opFadeIn {
	from { opacity: 0; }
	to   { opacity: 1; }
}
.op-dropdown > li > a {
	padding:8px 20px;
	transition:all .15s ease;
	outline:0;
	font-size:14px;
}
.op-dropdown > li > a:hover {
	padding-left:24px;
}
.op-dropdown .divider { margin:4px 0; height:0; overflow:hidden; border-top:1px solid #e5e5e5; list-style:none; }

/* 各操作项语义色（规范调色板，全站统一，避免同名不同色） */
.op-item-add      { color:#31708f; }
.op-item-add:hover      { background-color:#f0f4f8; color:#245269; }
.op-item-copy     { color:#8a6d3b; }
.op-item-copy:hover     { background-color:#faf6f0; color:#66512c; }
.op-item-edit     { color:#f0ad4e; }
.op-item-edit:hover     { background-color:#fef9f0; color:#ec971f; }
.op-item-check    { color:#31708f; }
.op-item-check:hover    { background-color:#f0f4f8; color:#245269; }
.op-item-delete   { color:#a94442; }
.op-item-delete:hover   { background-color:#fdf0f0; color:#843534; }
.op-item-transfer { color:#8a6d3b; }
.op-item-transfer:hover { background-color:#faf5ed; color:#66512c; }
.op-item-family   { color:#337ab7; }
.op-item-family:hover   { background-color:#f0f4f8; color:#2e6da4; }
.op-item-create   { color:#5cb85c; }
.op-item-create:hover   { background-color:#f0f9f0; color:#4cae4c; }
.op-item-export   { color:#777; }
.op-item-export:hover   { background-color:#f5f5f5; color:#555; }
.op-item-import   { color:#31708f; }
.op-item-import:hover   { background-color:#f0f4f8; color:#245269; }
