/* =============================================================================
   StuLink 主题层（浅色 / 深色）—— v1.19.70.64（2026-10-13）
   -----------------------------------------------------------------------------
   背景：此前全站颜色是「字面量满天飞」——base.html 内联 56 处、业务 css 201 处、
   模板内联 style 665 处；成绩分析（考试态 .sidebar-float）侧栏是白底卡，
   其它模块侧栏是深色 #1e293b，风格不统一。

   方案：Bootstrap 5.3.3 原生支持 data-bs-theme="dark"，但业务字面量优先级更高，
   所以这里做两层：
     L1 变量层：--sl-* 语义变量（两套值），并把 base.html 骨架改为引用变量；
     L2 兜底层：对「改不到的」外部 css / 模板内联 style，用属性选择器 +
        工具类覆盖（.bg-white / [style*="background:#fff"] …），深色下不再出现白块。

   加载位置：必须在 bootstrap.min.css **之后**（base.html 中位于 grades.css 之后），
   以便同特异性下由本文件胜出。
   ============================================================================= */

/* ============ 浅色（默认）：视觉保持与改造前一致，避免既有页面回归 ============ */
:root,
[data-bs-theme="light"] {
    /* —— 页面与面板 —— */
    /* 2026-10-13（v1.19.70.64）：页面底色原 #f0f2f5 偏灰，整体提亮一档 */
    --sl-bg: #f6f8fb;                  /* 页面底色 */
    --sl-surface: #ffffff;             /* 卡片 / 面板 / 弹层 */
    --sl-surface-2: #f8fafc;           /* 次级面：表头、卡片头、斑马行 */
    --sl-surface-3: #f1f5f9;           /* hover / 分组头 */
    --sl-border: #e2e8f0;              /* 分割线、边框 */
    /* 2026-10-13：课表（schedule_matrix.css / _schedule_grid.html）不再写死这三个色，
       浅色值与原来完全一致，深色下跟随主题 */
    --sl-line: #eef2f7;                /* 表格细网格线 */
    --sl-head-soft: #eef2f7;           /* 浅灰表头 / 矩阵次级底 */
    --sl-accent: #1d4ed8;              /* 强调色（表头链接 / 激活态） */
    --sl-text: #1e293b;                /* 主文字 */
    --sl-text-muted: #64748b;          /* 次要文字 */
    --sl-text-subtle: #94a3b8;         /* 更弱文字 */
    --sl-shadow: 0 1px 3px rgba(0, 0, 0, .08);

    /* —— 侧栏（普通侧栏与考试态侧栏共用同一套，风格统一） ——
       2026-10-13 修正：此前两套主题里侧栏都是深色（#1e293b / #131c2e），
       切到浅色模式后「只有内容区变亮、侧栏仍是一块深色」→ 视觉割裂（用户反馈）。
       现在侧栏跟随主题：浅色=白底深字，深色=深底浅字。 */
    --sl-sidebar-bg: #ffffff;
    --sl-sidebar-text: #475569;
    --sl-sidebar-text-hover: #1e293b;
    --sl-sidebar-title: #0f172a;       /* 侧栏内标题/强调 */
    --sl-sidebar-muted: #94a3b8;
    --sl-sidebar-hover: #f1f5f9;
    --sl-sidebar-active: #eff6ff;
    --sl-sidebar-active-text: #1d4ed8; /* 激活项文字（此前写死 #fff，浅侧栏下看不见） */
    --sl-sidebar-accent: #2563eb;      /* 激活竖条 */
    --sl-sidebar-accent-text: #1d4ed8; /* 激活/悬浮文字 */
    --sl-sidebar-line: #eef2f7;
    --sl-sidebar-group: #f8fafc;
    --sl-sidebar-chip: #e2e8f0;
    --sl-sidebar-done-bg: #dcfce7;     /* 已完成环节（绿点） */
    --sl-sidebar-done-text: #166534;

    /* —— 导航栏：同样跟随主题（原为写死深色 navbar-dark bg-dark）—— */
    --sl-navbar-bg: #ffffff;
    --sl-navbar-text: #1e293b;
    --sl-navbar-border: #e2e8f0;

    /* —— 表格 ——
       2026-10-13（v1.19.70.64）：成绩类表头原是写死的深色 #1e293b + 白字
       （grades.css 加了 !important）。页面整体主题化后这条黑表头就成了突兀的
       「黑条」（用户反馈「页面区域还有黑色的，比如表头」）→ 改为跟随主题：
       浅色 = 浅灰底深字，深色 = 深底浅字。 */
    --sl-head-bg: #e7ecf3;             /* 表头第 1 行（分组/大标题） */
    --sl-head-bg-2: #f1f4f9;           /* 表头第 2 行（各子列，浅一档形成层级） */
    /* 2026-10-28：任课矩阵「班主任」三列的表头底色（= --sl-head-bg 88% + 绿 12%）。
       原先用 color-mix() 现场算，旧内核（Chrome <111 / 微信 X5）直接丢弃该声明，
       班主任列就没了区隔色；改成两套主题各给一个算好的字面值。 */
    --sl-head-accent-bg: #cee0e6;
    --sl-head-text: #334155;
    --sl-head-border: #d5dde8;
    --sl-th-bg: #f1f4f9;               /* 普通单行表头 */
    --sl-th-text: #64748b;
    --sl-row-hover: #e0ecff;
    --sl-freeze-bg: #ffffff;           /* 冻结列（年级/班级） */
    --sl-subtotal-bg: #eef4fb;         /* 小计行 */
    --sl-grand-bg: #dfe9f6;            /* 总计行 */
    --sl-zebra-bg: #f8fafc;            /* 斑马行 */
    --sl-extra-bg: #fff8e6;            /* 「不在当前模板内」的层（划线分层） */

    /* 同步 Bootstrap 变量（浅色下即为 Bootstrap 默认值，显式写出防被上游污染） */
    --bs-body-bg: #f0f2f5;
    --bs-body-color: #1e293b;
    --bs-border-color: #dee2e6;
    --bs-secondary-bg: #e9ecef;
    /* 2026-10-13：Bootstrap 的卡片底色默认取 --bs-body-bg（#f0f2f5 灰），
       比页面底色 #f6f8fb 还暗 → "卡片比页面还脏、表格一片灰"。
       统一让卡片用面板白（深色下为深面板色），层级变成「灰页面 + 白卡片」。 */
    --bs-card-bg: var(--sl-surface);
    --bs-tertiary-bg: #f8f9fa;
    --bs-secondary-color: #64748b;
    --bs-emphasis-color: #1e293b;

    /* —— 语义软底（调课格 / 状态胶囊 / 提示块）——
       2026-10-13（调课页颜色调整）：调课各页在模板 <style> 里写死了浅底深字
       （#ecfdf5/#fef9c3/#f3e8ff …），深色主题下模板类声明不在 L2 兜底范围内，
       会"浅底浅字"直接看不见。这里把语义色提为变量：浅色值 = 原字面量，
       深色值 = 低饱和半透明底 + 亮字，模板只引用变量，不再写死颜色。 */
    --sl-soft-info-bg: #eff6ff;    --sl-soft-info-fg: #1e40af;    --sl-soft-info-bd: #bfdbfe;
    --sl-soft-success-bg: #ecfdf5; --sl-soft-success-fg: #065f46; --sl-soft-success-bd: #a7f3d0;
    --sl-soft-warn-bg: #fef9c3;    --sl-soft-warn-fg: #854d0e;    --sl-soft-warn-bd: #fde047;
    --sl-soft-amber-bg: #fff7ed;   --sl-soft-amber-fg: #9a3412;   --sl-soft-amber-bd: #fed7aa;
    --sl-soft-danger-bg: #fef2f2;  --sl-soft-danger-fg: #b91c1c;  --sl-soft-danger-bd: #fecaca;
    --sl-soft-purple-bg: #f3e8ff;  --sl-soft-purple-fg: #6b21a8;  --sl-soft-purple-bd: #d8b4fe;

    /* —— 图表调色板 / 语义单色 / 热力图渐变（2026-10-14）——
       ECharts 的颜色写在 JS 里（grades.js / student_query.js / inspection.js …），
       CSS 兜底选择器够不到，只能由脚本读变量后再交给 setOption。
       槽位语义固定：1 蓝 2 紫 3 绿 4 橙 5 红 6 青 7 粉 8 黄绿 9 橙红 10 靛，
       两套主题只换明度、不换槽位 → 同一张图在深浅两模式下「哪根是哪根」不变。
       浅色值 = 改造前的字面量，保证既有页面观感不变。 */
    --sl-chart-1: #3b82f6;
    --sl-chart-2: #8b5cf6;
    --sl-chart-3: #10b981;
    --sl-chart-4: #f59e0b;
    --sl-chart-5: #ef4444;
    --sl-chart-6: #06b6d4;
    --sl-chart-7: #ec4899;
    --sl-chart-8: #84cc16;
    --sl-chart-9: #f97316;
    --sl-chart-10: #6366f1;
    /* 语义单色（参考线 / 状态柱 / 面积图）：红黄绿仍要能区分，只提亮不换色相 */
    --sl-chart-ok: #10b981;
    --sl-chart-warn: #f59e0b;
    --sl-chart-danger: #ef4444;
    --sl-chart-info: #3b82f6;
    --sl-chart-purple: #6366f1;
    --sl-chart-cyan: #0ea5e9;
    --sl-chart-muted: #94a3b8;   /* 灰柱 / 参考线（workbench_grades 的“其它班”） */
    /* 热力图渐变：低值 → 高值。浅色 = 浅蓝 → 深蓝（原值） */
    --sl-heat-1: #eff6ff;
    --sl-heat-2: #93c5fd;
    --sl-heat-3: #3b82f6;
    --sl-heat-4: #1d4ed8;
    --sl-heat-label: #0f172a;    /* 格内数字：深色底上用亮字，浅色底上用深字 */
}

/* ============================ 深色 ============================ */
[data-bs-theme="dark"] {
    --sl-bg: #0f172a;
    --sl-surface: #172033;
    --sl-surface-2: #1c2739;
    --sl-surface-3: #233047;
    --sl-border: #2b3a52;
    --sl-line: rgba(255, 255, 255, .10);
    --sl-head-soft: #1c2739;
    --sl-accent: #93c5fd;
    --sl-text: #eef2f8;
    /* 2026-10-22 用户口径：深色下"次要文字"太暗（标签 / 图例 / 轴文字看不清），
       整体提亮一档：muted #94a3b8→#b6c3d6，subtle #64748b→#94a3b8。 */
    --sl-text-muted: #b6c3d6;
    --sl-text-subtle: #94a3b8;
    --sl-shadow: 0 1px 3px rgba(0, 0, 0, .45);

    /* 深色：侧栏与顶栏转深底浅字（比页面底色略深一档，形成层次） */
    --sl-sidebar-bg: #131c2e;
    --sl-sidebar-text: #cbd5e1;
    --sl-sidebar-text-hover: #f1f5f9;
    --sl-sidebar-title: #f8fafc;
    --sl-sidebar-muted: #a3b3c9;
    --sl-sidebar-hover: rgba(255, 255, 255, .07);
    --sl-sidebar-active: rgba(59, 130, 246, .20);
    --sl-sidebar-active-text: #f1f5f9;
    --sl-sidebar-accent: #60a5fa;
    --sl-sidebar-accent-text: #93c5fd;
    --sl-sidebar-line: rgba(255, 255, 255, .10);
    --sl-sidebar-group: rgba(255, 255, 255, .05);
    --sl-sidebar-chip: rgba(255, 255, 255, .14);
    --sl-sidebar-done-bg: rgba(22, 163, 74, .25);
    --sl-sidebar-done-text: #86efac;

    --sl-navbar-bg: #131c2e;
    --sl-navbar-text: #e2e8f0;
    --sl-navbar-border: #2b3a52;

    --sl-head-bg: #253149;             /* 第 1 行表头（深色下略亮，形成层级） */
    --sl-head-bg-2: #1c2739;           /* 第 2 行表头 */
    --sl-head-accent-bg: #243b50;      /* 班主任列表头（同浅色口径的深色版） */
    --sl-head-text: #e2e8f0;
    --sl-head-border: #33456b;
    --sl-th-bg: #1c2739;
    --sl-th-text: #94a3b8;
    --sl-row-hover: #1e3a5f;
    --sl-freeze-bg: #172033;
    --sl-subtotal-bg: #1d2b42;
    --sl-grand-bg: #22334f;
    --sl-zebra-bg: #1b2537;
    --sl-extra-bg: #33291a;

    /* 同步 Bootstrap 变量：让 card / table / dropdown / modal / form 一起变暗 */
    --bs-body-bg: #0f172a;
    --bs-body-color: #e2e8f0;
    --bs-border-color: #2b3a52;
    --bs-secondary-bg: #1c2739;
    --bs-card-bg: var(--sl-surface);
    --bs-tertiary-bg: #233047;
    --bs-secondary-color: #94a3b8;
    --bs-emphasis-color: #f1f5f9;
    --bs-heading-color: #f1f5f9;
    --bs-link-color: #7cb0f7;
    --bs-link-hover-color: #a5c8fa;

    /* 语义软底（深色）：低饱和半透明底 + 亮字，供调课格 / 状态胶囊等引用 */
    --sl-soft-info-bg: rgba(59, 130, 246, .18);    --sl-soft-info-fg: #93c5fd;    --sl-soft-info-bd: rgba(59, 130, 246, .40);
    --sl-soft-success-bg: rgba(16, 185, 129, .16); --sl-soft-success-fg: #6ee7b7; --sl-soft-success-bd: rgba(16, 185, 129, .38);
    --sl-soft-warn-bg: rgba(234, 179, 8, .18);     --sl-soft-warn-fg: #fcd34d;    --sl-soft-warn-bd: rgba(234, 179, 8, .40);
    --sl-soft-amber-bg: rgba(249, 115, 22, .16);   --sl-soft-amber-fg: #fdba74;   --sl-soft-amber-bd: rgba(249, 115, 22, .38);
    --sl-soft-danger-bg: rgba(239, 68, 68, .16);   --sl-soft-danger-fg: #fca5a5;  --sl-soft-danger-bd: rgba(239, 68, 68, .38);
    --sl-soft-purple-bg: rgba(168, 85, 247, .18);  --sl-soft-purple-fg: #d8b4fe;  --sl-soft-purple-bd: rgba(168, 85, 247, .40);

    /* 图表调色板（深色）：同一槽位整体提亮一档（400 级），压在 #172033 面板上
       对比度 ≥ 3:1（图形/大字下限），且色相与浅色一一对应，语义不丢。 */
    --sl-chart-1: #60a5fa;
    --sl-chart-2: #a78bfa;
    --sl-chart-3: #34d399;
    --sl-chart-4: #fbbf24;
    --sl-chart-5: #f87171;
    --sl-chart-6: #22d3ee;
    --sl-chart-7: #f472b6;
    --sl-chart-8: #a3e635;
    --sl-chart-9: #fb923c;
    --sl-chart-10: #818cf8;
    --sl-chart-ok: #34d399;
    --sl-chart-warn: #fbbf24;
    --sl-chart-danger: #f87171;
    --sl-chart-info: #60a5fa;
    --sl-chart-purple: #818cf8;
    --sl-chart-cyan: #38bdf8;
    --sl-chart-muted: #64748b;
    /* 热力图（深色）：深 → 亮逆序，低值贴近面板底色（不再是一块刺眼白），
       并刻意**不**拉到最亮，保证格内亮字在 4 段色上都能读（≥3.4:1）。 */
    --sl-heat-1: #12263f;
    --sl-heat-2: #16375f;
    --sl-heat-3: #1d4ed8;
    --sl-heat-4: #3b82f6;
    --sl-heat-label: #f8fafc;

    color-scheme: dark;
}

[data-bs-theme="light"] { color-scheme: light; }

/* =============================================================================
   L1：骨架元素统一取变量（覆盖 base.html 内联与其它 css 的字面量）
   ============================================================================= */
body {
    background: var(--sl-bg) !important;
    color: var(--sl-text);
}

/* 导航栏：原来是写死的 navbar-dark bg-dark（永远深色），现跟随主题变量。
   注意 navbar 里的按钮用的是 Bootstrap 的 btn-outline-light（白字白边），
   在浅色顶栏上会"消失" —— 这里统一按主题重描边/重着色，两模式都要看得见。 */
.navbar {
    background-color: var(--sl-navbar-bg) !important;
    color: var(--sl-navbar-text);
    border-bottom: 1px solid var(--sl-navbar-border);
}
.navbar .navbar-brand,
.navbar .nav-link,
.navbar .btn-outline-light { color: var(--sl-navbar-text) !important; }
.navbar .btn-outline-light { border-color: var(--sl-navbar-border) !important; }
.navbar .btn-outline-light:hover,
.navbar .btn-outline-light:focus {
    background: var(--sl-sidebar-hover) !important;
    color: var(--sl-sidebar-accent-text) !important;
}
/* 深色顶栏上 hover 底色是半透明白，浅色下用主题 hover 色即可（上面已覆盖） */
.navbar .text-white { color: var(--sl-navbar-text) !important; }
/* 窄屏汉堡按钮：navbar-dark 的图标是白色描边 SVG，浅色顶栏下会「消失」 */
[data-bs-theme="light"] .navbar .navbar-toggler-icon {
    --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}
/* 汉堡按钮本体在浅色顶栏下改浅底深字（原来是 btn-dark 黑底） */
[data-bs-theme="light"] .navbar > .btn-dark {
    background-color: #fff !important; border-color: var(--sl-navbar-border) !important;
    color: var(--sl-navbar-text) !important;
}

/* 2026-10-14 用户口径：品牌后缀「成绩工作台 / 教务工作台 / 我的工作台…」（workbench_name()）。
   顶栏随主题变色（浅色=白底深字 / 深色=深底浅字），所以这里一律取变量、不写字面量；
   窄屏隐藏 —— 顶栏还有汉堡 / 主题 / 铃铛 / 用户菜单，带后缀会把品牌挤到换行。 */
.navbar .brand-module {
    margin-left: 8px; padding: 1px 9px; border-radius: 999px;
    font-size: 12px; font-weight: 500; vertical-align: 1px;
    color: var(--sl-navbar-text); opacity: .72;
    border: 1px solid var(--sl-navbar-border);
    background: var(--sl-surface-3);
}
@media (max-width: 575.98px) {
    .navbar .brand-module { display: none; }
}

/* 侧栏：普通侧栏 + 考试态 .sidebar-float（成绩分析）一律同源 —— 不再一黑一白 */
.sidebar,
.sidebar.sidebar-float {
    background: var(--sl-sidebar-bg) !important;
    color: var(--sl-sidebar-text);
    border-color: var(--sl-border);
}
.sidebar .nav-link { color: var(--sl-sidebar-text); }
.sidebar .nav-link:hover {
    color: var(--sl-sidebar-text-hover);
    background: var(--sl-sidebar-hover);
}
.sidebar .nav-link.active {
    color: var(--sl-sidebar-active-text);
    background: var(--sl-sidebar-active);
    border-left-color: var(--sl-sidebar-accent);
}
.sidebar .nav-section { color: var(--sl-sidebar-muted); }
.sidebar .aca-group[aria-expanded="true"] { color: var(--sl-sidebar-text-hover); }

/* 考试态侧栏内部（原白卡专属配色）→ 改为侧栏语义变量，深浅两模式都协调 */
.sidebar-float .efn-back { color: var(--sl-sidebar-muted); }
.sidebar-float .efn-back:hover {
    color: var(--sl-sidebar-accent-text);
    background: var(--sl-sidebar-hover);
}
.sidebar-float .efn-title { color: var(--sl-sidebar-title); }
/* 2026-10-21 侧栏去掉分步骤圆点（.efn-steps / .efn-dot / .efn-count） */
.sidebar-float .efn-item .text-muted { color: var(--sl-sidebar-muted) !important; }
.sidebar-float .efn-item { color: var(--sl-sidebar-text); }
.sidebar-float .efn-item:hover {
    background: var(--sl-sidebar-hover);
    color: var(--sl-sidebar-accent-text);
}
.sidebar-float .efn-item.active {
    background: var(--sl-sidebar-active);
    color: var(--sl-sidebar-accent-text);
    box-shadow: inset 3px 0 0 0 var(--sl-sidebar-accent);
}
.sidebar-float .efn-group { background: var(--sl-sidebar-group); color: var(--sl-sidebar-text); }
.sidebar-float .efn-group:hover { background: var(--sl-sidebar-hover); }
.sidebar-float .efn-group .bi { color: var(--sl-sidebar-muted); }
/* 2026-10-13：原 .efn-ai（侧栏「AI 智能导入」项）已并入「成绩导入」，相关样式随之删除 */
/* 激活项里的浅色 badge（如「未配置」）在深色侧栏下不必反白 */
.sidebar-float .badge.bg-light { background: var(--sl-sidebar-chip) !important; color: var(--sl-sidebar-text) !important; }

/* 卡片 / 统计卡 / 面板：Bootstrap 5.3 的 dark 已处理 .card，这里统一阴影与边框 */
.card, .stat-card, .chart-card, .tbl-card,
.modal-content, .offcanvas, .toast, .popover, .dropdown-menu {
    background-color: var(--sl-surface);
    color: var(--sl-text);
    border-color: var(--sl-border);
    box-shadow: var(--sl-shadow);
}
.card-header, .card-footer, .modal-header, .modal-footer, .offcanvas-header {
    background-color: var(--sl-surface-2);
    border-color: var(--sl-border);
    color: var(--sl-text);
}
.list-group-item { background-color: var(--sl-surface); color: var(--sl-text); border-color: var(--sl-border); }
.list-group-item:hover { background-color: var(--sl-surface-2); }
.nav-tabs .nav-link { color: var(--sl-text-muted); }
.nav-tabs .nav-link.active { background: var(--sl-surface); color: var(--sl-text); border-color: var(--sl-border) var(--sl-border) var(--sl-surface); }
.nav-tabs { border-color: var(--sl-border); }
.page-link { background: var(--sl-surface); border-color: var(--sl-border); color: var(--sl-text); }
.page-link:hover { background: var(--sl-surface-2); color: var(--sl-text); }
.page-item.disabled .page-link { background: var(--sl-surface-2); color: var(--sl-text-subtle); }
.breadcrumb { --bs-breadcrumb-divider-color: var(--sl-text-subtle); }
.text-muted { color: var(--sl-text-muted) !important; }

/* 表格：表头 / 斑马 / 悬停用变量（Bootstrap dark 已改 --bs-table-*，这里补业务表） */
.table > thead th { color: var(--sl-th-text); }
/* 表头底色统一在第 1 行用 --sl-head-bg、第 2 行用 --sl-head-bg-2（见下方「两行表头」段） */
.table-striped > tbody > tr:nth-of-type(odd) > * { --bs-table-bg-type: var(--sl-zebra-bg); }

/* —— 成绩类表格（grades.css 用 !important 写死深色表头，必须逐个顶掉） —— */
.g-table thead th,
.g-table thead th:first-child,
.ld-table thead th {
    background: var(--sl-head-bg) !important;
    color: var(--sl-head-text) !important;
    border-color: var(--sl-head-border) !important;
}

/* =============================================================================
   两行表头 / 合并分组单元格：**层级用同族色阶**（纵深靠明度，不靠黑白对比）
   -----------------------------------------------------------------------------
   2026-10-13（v1.19.70.64）用户反馈：宽表「两行表头 + 合并单元格」样式割裂 ——
   第 1 行 #1e293b 深、第 2 行 #334155 次深、冻结列又回 #1e293b，
   与浅色表体拼在一起像三张表。现统一为：
     第 1 行（分组/大标题）→ --sl-head-bg（稍深）
     第 2 行（各子列）      → --sl-head-bg-2（稍浅一档）
     冻结列表头            → 同第 1 行（不再单独回写深色）
     表体 / 冻结列 / 斑马 / 小计总计 → 各自变量，全部跟随主题
   区块之间靠「同族明度差 + 统一 1px 分隔线」区分，不再靠黑白撞色。
   ============================================================================= */
.ld-table { border-color: var(--sl-head-border); }
/* 第 2 行表头（global_compare.css 里写死 #334155 + sticky top，这里只换色不动定位） */
.ld-table thead tr:nth-child(2) th {
    background: var(--sl-head-bg-2) !important;
    color: var(--sl-head-text) !important;
}
.ld-table thead th.grp { color: var(--sl-head-text) !important; }
/* 冻结列（年级/班级）：表头与第 1 行同色，表体与表体同色 —— 靠右分隔线区分区块 */
.ld-table thead th.c-year, .ld-table thead th.c-cls {
    background: var(--sl-head-bg) !important;
    color: var(--sl-head-text) !important;
    border-right: 1px solid var(--sl-head-border) !important;
}
.ld-table th.c-year, .ld-table td.c-year,
.ld-table th.c-cls, .ld-table td.c-cls {
    background: var(--sl-freeze-bg) !important;
}
.ld-table thead th.c-year, .ld-table thead th.c-cls {
    background: var(--sl-head-bg) !important;
}
.ld-table tbody td {
    background: var(--sl-surface);
    border-color: var(--sl-border) !important;
}
/* 小计 / 总计行：同族加深，不再用写死浅蓝 */
.ld-table tbody tr.sub td { background: var(--sl-subtotal-bg) !important; }
.ld-table tbody tr.grand td { background: var(--sl-grand-bg) !important; }
/* 方向/属性彩标在两套主题下都保持可读 */
.ld-dir-all { background: var(--sl-surface-3); color: var(--sl-text); }
.ld-type { color: var(--sl-text-muted); }

/* —— 通用表格：表头层级与表体（.table / 两行表头的第二行）—— */
.table thead th, .table-responsive thead th {
    background: var(--sl-head-bg) !important;
    color: var(--sl-head-text) !important;
    border-color: var(--sl-head-border) !important;
}
.table-responsive thead tr:nth-child(2) th {
    background: var(--sl-head-bg-2) !important;
    border-top: 1px solid var(--sl-head-border);
}
.table tbody td, .table-responsive tbody td { border-color: var(--sl-border); }
/* 合并分组列（rowspan 的「年级/班级」等）在表体里的底色统一为表体色 */
.table tbody th[scope="row"] { background: var(--sl-freeze-bg); color: var(--sl-text); }
.g-table tbody tr:nth-child(even) { background: var(--sl-zebra-bg) !important; --bs-table-bg: var(--sl-zebra-bg) !important; }
.g-table tbody tr:nth-child(even) td:first-child { background: var(--sl-zebra-bg) !important; }
.g-table tbody tr.stu-link:hover { background: var(--sl-row-hover) !important; }
.g-table tbody tr.stu-link:hover td:first-child { background: var(--sl-row-hover) !important; }
.g-table thead th.sortable:hover { color: var(--sl-sidebar-accent-text) !important; }
.g-table, .ld-table { color: var(--sl-text); border-color: var(--sl-border); }

/* =============================================================================
   表格统一（2026-10-13 用户反馈「边框还是不行 / padding 还是 margin」）
   -----------------------------------------------------------------------------
   症状①：.g-table 表头在 grades.css 里写了 `border-bottom: none`（当年配深色表头用），
          换成浅色表头后表头与表体之间**没有线**，整张表像"贴"在一起；
   症状②：表体横线是 grades.css 的 `1px dashed #dbe3ec`，与其它表的实线不是一套，
          深色模式下还是一道亮虚线；
   症状③：卡片底色默认取 --bs-body-bg（灰），比页面底色还暗 → 表格区域整体发灰；
   症状④：单元格里带输入框（划线分层）时，td 的边框 + input 的边框 = 格子套格子，
          且 input 宽度不足时数值被截断（426.5 → "426.!"）。
   统一口径：表头下 1px 实线（--sl-head-border）、表体横线 1px 实线（--sl-border）、
            宽表竖线同为 1px 实线、冻结列右侧加分隔线、单元格里的输入框不再自带边框。
   ============================================================================= */
.g-table thead th,
.table thead th,
.ld-table thead th {
    border-bottom: 1px solid var(--sl-head-border) !important;
}
/* 2026-10-13 用户口径：表格一律加**虚线**格线（表体横线 + 列线 + 外框）。
   表头下沿保留实线，作为「表头 / 表体」的分区线。 */
.g-table tbody td,
.table tbody td,
.ld-table tbody td {
    border-bottom: 1px dashed var(--sl-border) !important;
}
/* 冻结首列：右侧一条分隔线（横向滚动时「这一列不动」才有边界） */
.g-table thead th:first-child,
.g-table tbody td:first-child {
    border-right: 1px solid var(--sl-head-border) !important;
}
/* 例外：.table-borderless 是**刻意不要格线**的紧凑表（弹层清单 / 宿舍统计小表），
   上面几条是在"给所有表补线"，必须放行这一类，否则等于把它们的 borderless 抹掉 */
.table-borderless thead th,
.table-borderless tbody td,
.table-borderless > :not(caption) > * > * {
    border-bottom: 0 !important;
}
/* 宽表（全局对比 / 划线分层）：列多，靠竖线读列 */
.ld-table th, .ld-table td,
#bandTable th, #bandTable td {
    border-right: 1px dashed var(--sl-border);
}
.ld-table thead th, #bandTable thead th { border-right-color: var(--sl-head-border); }
.ld-table th:last-child, .ld-table td:last-child,
#bandTable th:last-child, #bandTable td:last-child { border-right: none; }

/* 2026-10-13 用户口径：**所有没有框线的普通表格**补虚线列线 + 虚线外框。
   - 只画 border，不碰 background / box-shadow：sticky 表头与冻结首列的底色、行 hover、
     斑马纹都是靠 --bs-table-* 变量与 inset box-shadow 画的，加了背景就全断；
   - .table-bordered 已自带实线外框、.table-borderless 刻意无线 → 两类都放行；
   - 末列去右边线，避免与表格外框叠成双线。 */
.table:not(.table-borderless):not(.table-bordered) > :not(caption) > * > * {
    border-right: 1px dashed var(--sl-border);
}
.table:not(.table-borderless):not(.table-bordered) > thead > tr > * {
    border-right-color: var(--sl-head-border);
}
.table:not(.table-borderless):not(.table-bordered) > :not(caption) > * > :last-child {
    border-right: 0;
}
.table:not(.table-borderless):not(.table-bordered) {
    border: 1px dashed var(--sl-border);
}
/* 打印：虚点在纸面上发灰，统一回实线 */
@media print {
    .table:not(.table-borderless) > :not(caption) > * > * {
        border-right: 1px solid var(--sl-border) !important;
        border-bottom: 1px solid var(--sl-border) !important;
    }
    .table:not(.table-borderless):not(.table-bordered) { border: 1px solid #e2e8f0; }
}

/* =============================================================================
   深色模式的语义行色（2026-10-13 用户反馈「暗黑模式下这些色块很突兀」）
   -----------------------------------------------------------------------------
   Bootstrap 5.3 编译产物里的 .table-success / .table-warning / .table-danger …
   是**主题无关的字面色**，[data-bs-theme=dark] 段没有重映射它们 → 考务②「考场库」
   已选行（<tr class="table-success">）在深色下整行亮绿，与深色底完全脱节。
   这里在深色下改成「低饱和半透明底 + 浅色字」；只设 --bs-table-* 变量（不写
   background），冻结首列与 hover 都能自动跟随。
   ============================================================================= */
[data-bs-theme="dark"] .table-success,
[data-bs-theme="dark"] .g-table tbody tr.table-success {
    --bs-table-bg: rgba(25, 135, 84, .16);
    --bs-table-color: #9ae6b4;
    --bs-table-border-color: rgba(25, 135, 84, .32);
    --bs-table-hover-bg: rgba(25, 135, 84, .26);
}
[data-bs-theme="dark"] .table-warning,
[data-bs-theme="dark"] .g-table tbody tr.table-warning {
    --bs-table-bg: rgba(255, 193, 7, .15);
    --bs-table-color: #fcd34d;
    --bs-table-border-color: rgba(255, 193, 7, .30);
    --bs-table-hover-bg: rgba(255, 193, 7, .24);
}
[data-bs-theme="dark"] .table-danger,
[data-bs-theme="dark"] .g-table tbody tr.table-danger {
    --bs-table-bg: rgba(220, 53, 69, .18);
    --bs-table-color: #f1aeb5;
    --bs-table-border-color: rgba(220, 53, 69, .34);
    --bs-table-hover-bg: rgba(220, 53, 69, .26);
}
[data-bs-theme="dark"] .table-info {
    --bs-table-bg: rgba(13, 202, 240, .14);
    --bs-table-color: #7ddfef;
    --bs-table-border-color: rgba(13, 202, 240, .30);
}
[data-bs-theme="dark"] .table-active {
    --bs-table-bg: var(--sl-surface-3);
    --bs-table-color: var(--sl-text);
}
/* .table-primary：调课详情「当前批次成员行」用，同样是写死浅蓝底 */
[data-bs-theme="dark"] .table-primary {
    --bs-table-bg: rgba(13, 110, 253, .18);
    --bs-table-color: var(--sl-text);
    --bs-table-border-color: rgba(13, 110, 253, .34);
}
/* .table-light 写死浅灰：深色下按面板色处理（表头 / 斑马行都用得多） */
[data-bs-theme="dark"] .table-light,
[data-bs-theme="dark"] thead.table-light > tr > * {
    --bs-table-bg: var(--sl-surface-2);
    --bs-table-color: var(--sl-text);
    --bs-table-border-color: var(--sl-border);
}

/* —— 划线分层（#bandTable）：整张表都是输入框 ——
   原来 input 的底色跟着页面/卡片底色走，与单元格底色不同 → "格子套格子"；
   现在 td 负责画格线与底色，input 只负责文字（透明底、无边框、聚焦才高亮），
   并给足宽度，避免 426.5 被截断成 "426.!"。 */
#bandTable tbody td { background: var(--sl-surface); padding: 5px 4px; }
/* 表格宽度与列宽（2026-10-13 用户反馈"表头"）：
   Bootstrap 的 .table 是 width:100%，只有「层名 + 总分」两列时两列各被撑到几百像素，
   表头看上去就是上下两条空色带。改为按内容收缩：层名列 300px、科目列统一 110px、
   操作列 56px，下限 min(100%, 620px) 免得缩成一张小卡片；
   分科（两组 × 7 科）内容更宽，在 .table-responsive 里横向滚动 ——
   与「全局对比」等宽表同一套交互。 */
/* 2026-10-14 浏览器兼容：旧版微信 X5（Chrome 57/66 内核）不认识 min()，
   整条声明会被丢弃 → 先写一条所有内核都懂的固定下限，再用 min() 提升。
   不支持的浏览器用第一行，支持的用第二行（后来者胜）。 */
#bandTable { width: max-content; min-width: 620px; min-width: min(100%, 620px); }
/* 字号随表格规模一起放大（2026-10-13 用户反馈"表格的宽度和文字大小很不协调"）：
   18 列铺到 2300px 宽时，12px 表头 / 12.5px 数字在大格子里显得又小又散。
   口径：表头 13px、格内数字 13.5px（其余成绩表仍是 12/12.5 —— 那些表列窄、行密，
   字号不能一起放大，这里只针对「宽格子 + 少内容」的划线分层）。 */
#bandTable thead th { font-size: 13px; }
/* 跨两行的表头格（层名 / 操作）垂直居中：Bootstrap 表头默认 vertical-align:bottom，
   会让「层名」「操作」两处文字掉到第 2 行的高度上，第 1 行左右两头各缺一块 ——
   用户看到的就是表头"裂了两条缝"（2026-10-13 反馈）。 */
#bandTable thead th { vertical-align: middle; }
/* 表头不做吸附。grades.css 的 `.g-table thead th` 带 position:sticky;top:0，
   在这个「内容比容器宽、会横向滚动」的表里，粘性定位会把**第 2 行**表头整体下推 5px，
   于是「层名」格的底边比右侧「总分」行的底边高出一截（用户反馈"没有对齐高度"）。
   本表最多几行层，垂直吸附本来也没用 —— 直接去掉 sticky，底边即对齐。 */
#bandTable thead th { position: static; }
/* 2026-10-21 用户反馈「表格有偏差」：表体首列（层名）是 sticky（base.html 的
   .table-responsive td:first-child），而上面刚把 thead 全部设为 static —— 表宽超过容器
   横向滚动时，表体层名列钉在左侧、表头整体左移，表头与数值列就对不上了。
   这里单独把**表头首列**也横向冻结（只 left，不 top，避免重新引入上一条说的下推问题）。 */
#bandTable thead th.col-layer {
    position: sticky; left: 0; top: auto; z-index: 4;
    background: var(--sl-head-bg);
    box-shadow: 2px 0 4px -2px rgba(15, 30, 61, .25);
}
/* 第 2 行表头的那条横分隔线在 rowspan 格（层名 / 操作）处必然断开，
   反而像一条裂缝；去掉它，两行表头用同族色阶（--sl-head-bg / -2）区分。 */
#bandTable thead tr:nth-child(2) th { border-top: 0 !important; }
/* 2026-10-21 用户口径：常用分辨率下尽量一屏显示完所有科目列 —— 列宽整体收窄。
   层名列原来 300px（层名只有「985线」几个字）太浪费，收到 120px；
   科目列 100px → 72px（格内是 3~5 个字符的数字，够用）。 */
#bandTable th.col-layer, #bandTable td:first-child { width: 120px; min-width: 96px; }
#bandTable th.col-sub, #bandTable td.q-sub { width: 72px; min-width: 60px; }
/* 操作列（删除按钮）窄、居中；表头格留空（与分层模板页一致） */
#bandTable th.col-op, #bandTable td:last-child { width: 56px; min-width: 52px; text-align: center; }
#bandTable tbody tr:nth-child(even) td { background: var(--sl-zebra-bg); }
/* 「模板外」的层（不在当前模板层名内、由已保存划线追加而来）：淡琥珀底 + 层名下标注
   —— 模板没选对时一眼可见，不再混在模板层里像补丁（用户口径 2026-10-13） */
#bandTable tbody tr.q-extra td { background: var(--sl-extra-bg) !important; }
/* 2026-11-03 用户口径：层名列文字**居中**（层名、模板提示、比例定义一并居中） */
#bandTable th.col-layer,
#bandTable td:first-child { text-align: center; }
#bandTable td:first-child .q-name { text-align: center; }
#bandTable td .q-tpl-mod { font-size: 10.5px; line-height: 1.25; white-space: normal; }
#bandTable td .form-control {
    background: transparent;
    border: 0;
    color: var(--sl-text);
    /* 13.5px：与 100px 列的格子成比例（原 12.5px 配 110px 格显得小） */
    font-size: 13.5px;
    padding: 4px 5px;
    min-width: 56px;
    height: auto;
}
#bandTable td .q-name { min-width: 0; width: 100%; }
/* 2026-10-21 用户反馈：层名列（120/112px）里的「模板定义：比例 50% · 约 210 人」
   是一整行不换行的文本，会横向溢出压到右边「总分」格上。允许换行并按格宽折行；
   比例/名次口径下这行最多两行，行高可控。 */
#bandTable td:first-child { white-space: normal; }
#bandTable td .q-tpl-def {
    font-size: 10.5px;
    line-height: 1.25;
    white-space: normal;
    word-break: break-word;
    overflow-wrap: anywhere;
}
#bandTable td .q-cell { text-align: center; font-variant-numeric: tabular-nums; }
/* —— 组合线格（.q-selrow / .q-sel-name / .q-selcell，2026-10-15）——
   上面「td .form-control」把全表 input 的边框与底色去掉了，组合格因此看不出
   「这里能填」（用户反馈原话「你这个框不是很明显啊」）：给组合格一个
   2px 强调色实线框 + 面板底，深浅色都走变量；
   组合名做成小标签，与右侧输入框成一组，一眼能读出「哪个组合的线」。 */
#bandTable td .q-selrow { gap: 4px; }
#bandTable td .q-sel-name {
    font-size: 11px;
    line-height: 1.35;
    padding: 1px 5px;
    border-radius: 4px;
    border: 1px solid var(--sl-border);
    background: var(--sl-surface-3);
    color: var(--sl-text-muted);
    white-space: nowrap;
}
#bandTable td .q-selcell {
    width: 4.2em;
    flex: 0 0 auto;
    border: 2px solid var(--sl-accent);
    background: var(--sl-surface);
    text-align: center;
    font-variant-numeric: tabular-nums;
}
/* 2026-10-21 宽屏自适应列宽：≥1200px 时整表铺满容器、科目列均分（不再横向滚动）；
   更窄的屏幕仍按上面的最小列宽排版，必要时横向滚动，不会把数字挤没。 */
@media (min-width: 1200px) {
    #bandTable { width: 100%; table-layout: fixed; }
    #bandTable th.col-layer, #bandTable td:first-child { width: 112px; min-width: 0; }
    #bandTable th.col-sub, #bandTable td.q-sub { width: auto; min-width: 0; }
    #bandTable th.col-op, #bandTable td:last-child { width: 48px; min-width: 0; }
    #bandTable td .form-control { min-width: 0; }
    /* 组合格（组合名 + 输入框）在窄列里改为上下排，避免横向溢出 */
    #bandTable td .q-selrow { flex-wrap: wrap; }
    #bandTable td .q-selcell { width: 100%; }
}
#bandTable td .form-control:focus {
    background: var(--sl-surface);
    box-shadow: 0 0 0 2px var(--sl-sidebar-accent);
    border-radius: 3px;
}
/* 页面模板里内联写死的深色表头/横幅（内联优先级高于本文件，必须用 !important 顶掉）：
   - academic/schedule_periods.html：table.tt thead th（节次表）
   - academic/subject_leaders.html：.ld-head（备课组长分组头）
   - academic/index.html：.ac-hero（教务工作台横幅，原本深色渐变 + 白字） */
table.tt thead th {
    background: var(--sl-head-bg) !important;
    color: var(--sl-head-text) !important;
}
.ld-head {
    background: var(--sl-head-bg) !important;
    color: var(--sl-head-text) !important;
}
.ac-hero {
    background: linear-gradient(120deg, var(--sl-head-bg),
                var(--sl-surface-2) 60%, var(--sl-surface-3)) !important;
    color: var(--sl-text) !important;
}
.ac-hero h4, .ac-hero .ac-hero-meta strong { color: var(--sl-text) !important; }
.ac-hero .ac-hero-meta { opacity: .8; }
.chart-card .card-header, .tbl-card .card-header {
    background: var(--sl-surface-2);
    border-bottom: 1px solid var(--sl-border);
}
.empty-state { color: var(--sl-text-muted); }
.empty-state .bi { color: var(--sl-text-subtle); }
.chart-tip { color: var(--sl-text-muted); }
#gCmList .cm-item:hover { background: var(--sl-surface-3); }

/* —— 课表总览（schedule_matrix.css） —— */
.ovw-block { border-color: var(--sl-border); }
.ovw-block-head {
    background: linear-gradient(90deg, var(--sl-sidebar-bg), var(--sl-surface-2)) !important;
    /* color 也必须 !important：schedule_matrix.css 是**页面引入**的（在 theme.css 之后加载），
       里面写死 `color:#f1f5f9`（当年块头是深色渐变时的配套字色）。背景已被本条改成浅色，
       字色没有 !important 就被它赢回浅色 → 浅色主题下「白底浅字」整条块头看不见（对比 1.1）。 */
    color: var(--sl-sidebar-text-hover) !important;
}
.ovw-block-head .ovw-sub { color: var(--sl-sidebar-muted); }
.ovw-table thead th { background: var(--sl-surface-2); color: var(--sl-text); }
.ovw-grp-row th, .ovw-per-row th { background: var(--sl-surface-2); color: var(--sl-text); }
.ovw-period-name, .ovw-cmeta { color: var(--sl-text-muted); }
.ovw-grp-break { color: var(--sl-text-muted) !important; }
.ovw-teacher { color: var(--sl-text-muted); }
.ovw-cell, .ovw-blank { border-color: var(--sl-border); }
/* 2026-10-16 删除：这里原有一条 `.ovw-chk-none{background:var(--sl-surface-3)}`，
   但 schedule_matrix.css 在 theme.css **之后**加载、特异性相同（0,1,0）→ 实际生效的是
   schedule_matrix.css:81 的 `background:var(--sl-border)`（实测 rgb(226,232,240)），
   本条从未生效（死规则）。删掉避免后人"改这里没反应"；
   深色下 6 个状态徽标由下面的 [data-bs-theme="dark"] .ovw-chk-* 接管。 */

/* =============================================================================
   L2：兜底 —— 覆盖「改不到的」模板内联 style 与 Bootstrap 浅色工具类
   （模板里有 665 行内联色，逐个改不现实；用属性选择器批量接管白底/深色字）
   ============================================================================= */
[data-bs-theme="dark"] .bg-white,
[data-bs-theme="dark"] .bg-light,
[data-bs-theme="dark"] [style*="background:#fff"],
[data-bs-theme="dark"] [style*="background: #fff"],
[data-bs-theme="dark"] [style*="background:#ffffff"],
[data-bs-theme="dark"] [style*="background: #ffffff"],
[data-bs-theme="dark"] [style*="background-color:#fff"],
[data-bs-theme="dark"] [style*="background-color: #fff"] {
    background: var(--sl-surface) !important;
}
[data-bs-theme="dark"] [style*="background:#f8f9fa"],
[data-bs-theme="dark"] [style*="background: #f8f9fa"],
[data-bs-theme="dark"] [style*="background:#f8fafc"],
[data-bs-theme="dark"] [style*="background: #f8fafc"],
[data-bs-theme="dark"] [style*="background:#f1f5f9"],
[data-bs-theme="dark"] [style*="background: #f1f5f9"],
[data-bs-theme="dark"] [style*="background:#f6f8fb"],
[data-bs-theme="dark"] [style*="background: #f6f8fb"] {
    background: var(--sl-surface-2) !important;
}
[data-bs-theme="dark"] [style*="color:#333"],
[data-bs-theme="dark"] [style*="color: #333"],
[data-bs-theme="dark"] [style*="color:#000"],
[data-bs-theme="dark"] [style*="color: #000"],
[data-bs-theme="dark"] [style*="color:#212529"],
[data-bs-theme="dark"] [style*="color: #212529"],
[data-bs-theme="dark"] .text-dark,
[data-bs-theme="dark"] .text-black {
    color: var(--sl-text) !important;
}
[data-bs-theme="dark"] [style*="background:#1e293b"],
[data-bs-theme="dark"] [style*="background: #1e293b"] {
    background: var(--sl-sidebar-bg) !important;
}

/* —— 成绩汇报区（report.js 内联样式 + report.css）——
   表格底色/文字是 JS 内联输出的（复制进 PPT 要保样式），只能靠属性选择器兜底。
   此前 #f3f5f9 斑马行 / #1a1a1a·#222 深字不在兜底清单里：
   深色下普通行「深底深字」→ 文字隐身，斑马行变成亮白条（用户反馈"颜色表格"）。 */
[data-bs-theme="dark"] [style*="background:#f3f5f9"],
[data-bs-theme="dark"] [style*="background: #f3f5f9"],
[data-bs-theme="dark"] [style*="background:#eef3fa"],
[data-bs-theme="dark"] [style*="background: #eef3fa"],
[data-bs-theme="dark"] [style*="background:#dbe7f5"],
[data-bs-theme="dark"] [style*="background: #dbe7f5"] {
    background: var(--sl-surface-3) !important;
}
[data-bs-theme="dark"] [style*="color:#1a1a1a"],
[data-bs-theme="dark"] [style*="color: #1a1a1a"],
[data-bs-theme="dark"] [style*="color:#222"],
[data-bs-theme="dark"] [style*="color: #222"] {
    color: var(--sl-text) !important;
}
[data-bs-theme="dark"] [style*="color:#444"],
[data-bs-theme="dark"] [style*="color: #444"],
[data-bs-theme="dark"] [style*="color:#666"],
[data-bs-theme="dark"] [style*="color: #666"],
[data-bs-theme="dark"] [style*="color:#888"],
[data-bs-theme="dark"] [style*="color: #888"],
[data-bs-theme="dark"] [style*="color:#999"],
[data-bs-theme="dark"] [style*="color: #999"] {
    color: var(--sl-text-muted) !important;
}
/* 名次列的蓝字（#1f4e79）在深色下换成亮蓝；表头深蓝底保留（白字可读） */
[data-bs-theme="dark"] [style*="color:#1f4e79"] {
    color: var(--sl-sidebar-accent-text) !important;
}
/* 单元格 1.5px 深蓝描边在深色下调暗，避免整表"发蓝" */
[data-bs-theme="dark"] [style*="solid #2b5f9e"] {
    border-color: var(--sl-border) !important;
}
/* report.css（屏幕样式）里的深字标题 / 灰字说明 */
[data-bs-theme="dark"] .rp-title h6 { color: var(--sl-text) !important; }
[data-bs-theme="dark"] .rp-title .rp-sub,
[data-bs-theme="dark"] .rp-hint,
[data-bs-theme="dark"] .rp-rank-opt { color: var(--sl-text-muted) !important; }
[data-bs-theme="dark"] ::-webkit-scrollbar { width: 10px; height: 10px; }
[data-bs-theme="dark"] ::-webkit-scrollbar-track { background: var(--sl-bg); }
[data-bs-theme="dark"] ::-webkit-scrollbar-thumb { background: #35465f; border-radius: 5px; }


/* 反向问题：模板里写死的「深色文字」（宿舍床位姓名、调课节次等）在深色卡片上看不清 */
[data-bs-theme="dark"] .bed-student,
[data-bs-theme="dark"] .ep-pn,
[data-bs-theme="dark"] .ld-duty,
[data-bs-theme="dark"] .ld-members { color: var(--sl-text) !important; }

/* =============================================================================
   L3：暗色可读性补漏（2026-10-13 用户反馈「考试概览页夜色模式下啥也看不见」）
   -----------------------------------------------------------------------------
   L2 的 `[style*="..."]` 只匹配**内联 style 属性**，管不到模板 <style> 块里的类选择器，
   而"看不见"的重灾区恰好在那里（成绩单姓名/总分列，已在各模板内改用 --sl-*）。
   这里补三类：
     1) Bootstrap 静态语义类：.alert-light 深色下不重映射，永远是一条浅底白条；
     2) 内联浅色底 / 深色字的白名单扩容（语义浅底映射成低饱和语义色，不丢语义）；
     3) 模板 <style> 块里写死深字的类，逐条点名（只作用于深色，不影响亮色与打印）。
   ============================================================================= */
[data-bs-theme="dark"] .alert-light {
    --bs-alert-bg: var(--sl-surface-2);
    --bs-alert-color: var(--sl-text);
    --bs-alert-border-color: var(--sl-border);
    --bs-alert-link-color: var(--sl-sidebar-accent-text);
}
/* —— 内联浅底：按语义映射成低饱和底，保留「这个块在提示什么」—— */
[data-bs-theme="dark"] [style*="background:#fef3c7"],
[data-bs-theme="dark"] [style*="background: #fef3c7"],
[data-bs-theme="dark"] [style*="background:#fffbeb"],
[data-bs-theme="dark"] [style*="background: #fffbeb"],
[data-bs-theme="dark"] [style*="background:#fff7ed"],
[data-bs-theme="dark"] [style*="background: #fff7ed"],
[data-bs-theme="dark"] [style*="background:#fef9c3"],
[data-bs-theme="dark"] [style*="background: #fef9c3"] {
    background: rgba(255, 193, 7, .14) !important;
}
[data-bs-theme="dark"] [style*="background:#e0e7ff"],
[data-bs-theme="dark"] [style*="background: #e0e7ff"],
[data-bs-theme="dark"] [style*="background:#f5f3ff"],
[data-bs-theme="dark"] [style*="background: #f5f3ff"] {
    background: rgba(99, 102, 241, .18) !important;
}
[data-bs-theme="dark"] [style*="background:#eff6ff"],
[data-bs-theme="dark"] [style*="background: #eff6ff"],
[data-bs-theme="dark"] [style*="background:#e0f2fe"],
[data-bs-theme="dark"] [style*="background: #e0f2fe"],
[data-bs-theme="dark"] [style*="background:#dbeafe"],
[data-bs-theme="dark"] [style*="background: #dbeafe"],
[data-bs-theme="dark"] [style*="background:#eef2ff"],
[data-bs-theme="dark"] [style*="background: #eef2ff"] {
    background: rgba(13, 110, 253, .16) !important;
}
[data-bs-theme="dark"] [style*="background:#fef2f2"],
[data-bs-theme="dark"] [style*="background: #fef2f2"],
[data-bs-theme="dark"] [style*="background:#fee2e2"],
[data-bs-theme="dark"] [style*="background: #fee2e2"] {
    background: rgba(220, 53, 69, .16) !important;
}
[data-bs-theme="dark"] [style*="background:#ecfdf5"],
[data-bs-theme="dark"] [style*="background: #ecfdf5"],
[data-bs-theme="dark"] [style*="background:#f0fdf4"],
[data-bs-theme="dark"] [style*="background: #f0fdf4"],
[data-bs-theme="dark"] [style*="background:#dcfce7"],
[data-bs-theme="dark"] [style*="background: #dcfce7"] {
    background: rgba(25, 135, 84, .16) !important;
}
[data-bs-theme="dark"] [style*="background:#e2e8f0"],
[data-bs-theme="dark"] [style*="background: #e2e8f0"],
[data-bs-theme="dark"] [style*="background:#e5e7eb"],
[data-bs-theme="dark"] [style*="background: #e5e7eb"],
[data-bs-theme="dark"] [style*="background:#f5f5f5"],
[data-bs-theme="dark"] [style*="background: #f5f5f5"],
[data-bs-theme="dark"] [style*="background:#f9fafb"],
[data-bs-theme="dark"] [style*="background: #f9fafb"],
[data-bs-theme="dark"] [style*="background:#fbfcfd"],
[data-bs-theme="dark"] [style*="background: #fbfcfd"],
[data-bs-theme="dark"] [style*="background:#eef2f7"],
[data-bs-theme="dark"] [style*="background: #eef2f7"] {
    background: var(--sl-surface-2) !important;
}
/* —— 内联深色文字：深底上必须提亮（近黑 / 深灰一起覆盖）—— */
[data-bs-theme="dark"] [style*="color:#1e293b"],
[data-bs-theme="dark"] [style*="color: #1e293b"],
[data-bs-theme="dark"] [style*="color:#0f172a"],
[data-bs-theme="dark"] [style*="color: #0f172a"],
[data-bs-theme="dark"] [style*="color:#111827"],
[data-bs-theme="dark"] [style*="color: #111827"],
[data-bs-theme="dark"] [style*="color:#0f1e3b"] {
    color: var(--sl-text) !important;
}
[data-bs-theme="dark"] [style*="color:#334155"],
[data-bs-theme="dark"] [style*="color: #334155"],
[data-bs-theme="dark"] [style*="color:#475569"],
[data-bs-theme="dark"] [style*="color: #475569"],
[data-bs-theme="dark"] [style*="color:#495057"],
[data-bs-theme="dark"] [style*="color: #495057"],
[data-bs-theme="dark"] [style*="color:#6c757d"],
[data-bs-theme="dark"] [style*="color: #6c757d"],
[data-bs-theme="dark"] [style*="color:#6b7280"] {
    color: var(--sl-text-muted) !important;
}
/* —— 模板 <style> 块：逐条点名的深色文字（类选择器，L2 的属性选择器管不到）—— */
[data-bs-theme="dark"] .detail-content,
[data-bs-theme="dark"] .cmp-val,
[data-bs-theme="dark"] .cmp-big,
[data-bs-theme="dark"] .orig-course .subj,
[data-bs-theme="dark"] .ep-subj,
[data-bs-theme="dark"] .rd-berth-name,
[data-bs-theme="dark"] .sch-period-name { color: var(--sl-text) !important; }
[data-bs-theme="dark"] .rd-notes,
[data-bs-theme="dark"] .rd-berth-no { color: var(--sl-text-muted) !important; }
/* —— 无主题变体的浅色容器（课表网格外壳）—— */
[data-bs-theme="dark"] .sch-grid-wrap {
    background: var(--sl-surface) !important;
    border-color: var(--sl-border) !important;
}

/* =============================================================================
   L4：深色补漏 · 第二批（2026-10-14 全项目审计 B 组）
   -----------------------------------------------------------------------------
   前几批只覆盖了「内联 style 属性」与少数类；模板 <style> 与其它业务 css 里的
   **类选择器**仍是浅底深字（属性选择器兜底管不到类声明），深色下要么刺眼白块、
   要么与面板糊成一片。这批逐条点名，全部只用 var(--sl-*)，不新增写死色。
   涉及的源文件（模板 / grades.css / schedule_matrix.css / global_compare.css）
   都不在本批可改清单内，故一律在此覆盖。
   ============================================================================= */

/* —— 课表网格表头（_schedule_grid.html 写死 #1e293b→#273549 渐变 + 浅字）——
   浅色模式下是一条黑条（与浅色表体割裂），深色下又与表体同深度糊成一片。
   两套主题统一为「表头语义色 + 同族明度差」，sticky 定位不动。 */
.sch-grid thead th {
    background: var(--sl-head-bg) !important;
    color: var(--sl-head-text) !important;
    box-shadow: inset 0 -1px 0 var(--sl-head-border), 0 2px 6px var(--sl-shadow) !important;
}
.sch-grid thead th.sch-period-col { background: var(--sl-head-bg) !important; }

/* —— 查课 6 个状态徽标（schedule_matrix.css 写死浅底深字）——
   深色下改「低饱和半透明底 + 400 明度字」，色相不换：绿/黄/红/靛/蓝/灰仍可区分。 */
[data-bs-theme="dark"] .ovw-chk-normal { background: rgba(16, 185, 129, .18);  color: #6ee7b7; }
[data-bs-theme="dark"] .ovw-chk-late   { background: rgba(245, 158, 11, .18);  color: #fcd34d; }
[data-bs-theme="dark"] .ovw-chk-absent { background: rgba(239, 68, 68, .18);   color: #fca5a5; }
[data-bs-theme="dark"] .ovw-chk-swap   { background: rgba(99, 102, 241, .20);  color: #a5b4fc; }
[data-bs-theme="dark"] .ovw-chk-exam   { background: rgba(14, 165, 233, .20);  color: #7dd3fc; }
[data-bs-theme="dark"] .ovw-chk-other  { background: rgba(148, 163, 184, .18); color: #cbd5e1; }

/* —— 宿舍床位 / 学生条目（base.html 内联：#eff6ff 底、性别粉蓝底与 hover）—— */
[data-bs-theme="dark"] .bed-slot.occupied {
    background: var(--sl-surface-3) !important;
    border-color: var(--sl-sidebar-accent) !important;
}
[data-bs-theme="dark"] .bed-slot.empty:hover {
    background: rgba(16, 185, 129, .16) !important;
    border-color: #34d399 !important;
}
[data-bs-theme="dark"] .student-item.male-student {
    background: rgba(59, 130, 246, .10) !important;
    border-left-color: #60a5fa !important;
}
[data-bs-theme="dark"] .student-item.female-student {
    background: rgba(236, 72, 153, .10) !important;
    border-left-color: #f472b6 !important;
}
[data-bs-theme="dark"] .student-item.male-student:hover { background: rgba(59, 130, 246, .20) !important; }
[data-bs-theme="dark"] .student-item.female-student:hover { background: rgba(236, 72, 153, .20) !important; }

/* —— AI 对话区（grades.css 整块白底白卡：ai-chat / bubble / think / chart-card）——
   grades.css 在 base.html 里排在 theme.css **之前**，且本规则带属性选择器，必然胜出。 */
[data-bs-theme="dark"] .ai-chat {
    background: var(--sl-surface-2) !important;
    border-color: var(--sl-border) !important;
}
[data-bs-theme="dark"] .ai-bubble {
    background: var(--sl-surface) !important;
    border-color: var(--sl-border) !important;
    color: var(--sl-text) !important;
}
[data-bs-theme="dark"] .ai-msg-user .ai-bubble {
    background: var(--sl-sidebar-active) !important;
    border-color: var(--sl-sidebar-accent) !important;
    color: var(--sl-text) !important;
}
[data-bs-theme="dark"] .ai-bubble table th,
[data-bs-theme="dark"] .ai-bubble table td { border-color: var(--sl-border) !important; }
[data-bs-theme="dark"] .ai-bubble table th { background: var(--sl-surface-3) !important; }
[data-bs-theme="dark"] .ai-bubble code {
    background: var(--sl-surface-3) !important;
    color: var(--sl-text) !important;
}
[data-bs-theme="dark"] .ai-bubble blockquote {
    border-left-color: var(--sl-border) !important;
    color: var(--sl-text-muted) !important;
}
[data-bs-theme="dark"] .ai-think {
    background: var(--sl-surface-2) !important;
    border-color: var(--sl-border) !important;
}
[data-bs-theme="dark"] .ai-think summary,
[data-bs-theme="dark"] .ai-stage { color: var(--sl-text-muted) !important; }
[data-bs-theme="dark"] .ai-caret { background: var(--sl-sidebar-accent) !important; }
[data-bs-theme="dark"] .ai-chart-card {
    background: var(--sl-surface) !important;
    border-color: var(--sl-border) !important;
}
[data-bs-theme="dark"] .ai-chart-title { color: var(--sl-text) !important; }

/* —— 方向彩标 / 选科标签（global_compare.css + base.html 内联）—— */
[data-bs-theme="dark"] .ld-dir-phy { background: rgba(59, 130, 246, .18); color: #93c5fd; }
[data-bs-theme="dark"] .ld-dir-his { background: rgba(239, 68, 68, .16);  color: #fca5a5; }
[data-bs-theme="dark"] .subj-physics {
    background: rgba(59, 130, 246, .18); color: #93c5fd; border-color: rgba(59, 130, 246, .38) !important;
}
[data-bs-theme="dark"] .subj-history {
    background: rgba(249, 115, 22, .16); color: #fdba74; border-color: rgba(249, 115, 22, .38) !important;
}

/* —— 表单汇总迷你条（_fx_style.html 内联 #edf1f8，模板不在可改清单）—— */
[data-bs-theme="dark"] .fx-mini-bar { background: var(--sl-surface-3) !important; }

/* —— AI 提示词生成器（成绩汇报区 / AI 分析工作台共用，2026-10-14）——
   班级 / 学科多选用胶囊勾选（比 ctrl+多选下拉直观），选中态跟随主题 primary；
   面板底色用次级面，深浅主题自适应，不写死颜色（两侧模板都用同一套 class）。 */
.ai-gen-panel { background: var(--sl-surface-2); }
.ai-gen-chips .chip {
    font-size: 12px; padding: 1px 9px; border-radius: 999px; cursor: pointer;
    border: 1px solid var(--sl-border); background: var(--sl-surface); color: var(--sl-text);
}
.ai-gen-chips .chip:hover { border-color: var(--bs-primary); }
.ai-gen-chips .chip.on {
    border-color: var(--bs-primary); color: var(--bs-primary);
    background: var(--bs-primary-bg-subtle); font-weight: 600;
}
.ai-gen-chips .chip.chip-extra { border-style: dashed; }

/* =============================================================================
   移动端点击区（2026-10-14 审计）：触屏下把 12~24px 的小按钮撑到 40×40
   （WCAG 2.5.5 / 微信 X5 与手机浏览器点不准）。
   只在「无 hover + 粗指针」的触屏生效 —— 桌面（有 hover 的鼠标）观感完全不变。
   ============================================================================= */
@media (hover: none) and (pointer: coarse) {
    /* 2026-10-14 第四轮审计（UI-11）：原只覆盖「图标型」两个选择器，表格行内的
       「移出 / 加入 / 编辑」等 .btn-sm 仍只有 ~31px（点不准）。扩到全部 .btn-sm
       与表格内按钮：只加 min-height（不动横向布局）；图标型按钮继续强制 40×40。 */
    .btn-sm,
    .table .btn,
    .btn-close-sm {
        min-height: 40px;
    }
    .btn.btn-sm.py-0.px-1,
    .btn-close-sm {
        min-width: 40px;
    }
}

/* =============================================================================
   L4：语义色对比度兜底（2026-10-14 全站低对比审计）
   -----------------------------------------------------------------------------
   用 Playwright 遍历全站页面、按 WCAG 算实际对比度后发现的一类共性问题：
   Bootstrap 的语义色是「按深色底设计」的字面量，页面主题化后落在浅底上就偏淡
   甚至隐身 —— 与 L2/L3 不同，这类问题**与主题无关、任何页面都可能踩**：
     1) .btn-outline-* 是**透明底**；业务模板里常写成 btn-outline-info text-white
        （当年页面底是深色，白字可读）→ 浅色下白字透明底，对比 1.06（等于看不见）；
     2) .btn-info/.btn-warning 自带**黑字**，叠加 text-white 后反而降到 1.96；
     3) .text-info(#0dcaf0) / .text-warning(#ffc107) 在白底上只有 1.96 / 1.45。
   这里按「语义不变、对比度达标」就地修正，不去逐个模板改（模板里这类写法有 40+ 处）。
   ============================================================================= */
/* ① outline 按钮 + text-white = 白字透明底 → 补成实心语义底（用 Bootstrap 自己的 hover 配色） */
.btn-outline-info.text-white,
.btn-outline-primary.text-white,
.btn-outline-success.text-white,
.btn-outline-warning.text-white,
.btn-outline-danger.text-white,
.btn-outline-secondary.text-white,
.btn-outline-dark.text-white,
.btn-outline-light.text-white {
    /* .text-white 是 Bootstrap 工具类且自带 !important，这里必须同等级才能压住 */
    background-color: var(--bs-btn-hover-bg) !important;
    border-color: var(--bs-btn-hover-border-color) !important;
    color: var(--bs-btn-hover-color) !important;
}
/* ② 实心按钮自带深色字，被 text-white 压成白字 → 恢复 Bootstrap 自带字色 */
.btn-info.text-white,
.btn-warning.text-white,
.btn-light.text-white { color: var(--bs-btn-color) !important; }
/* ③ 浅色主题下这几个语义字色太淡（.text-info 1.96 / .text-warning 1.45；
   outline 按钮的字色同理：青 #0dcaf0、黄 #ffc107 在白底上几乎看不清）——
   换成同语义的深色，描边与边框一起加深，保持"outline"的轻量观感。
   深色主题下维持 Bootstrap 原值（亮色在深底上足够）。 */
[data-bs-theme="light"] .text-info { color: #0a8bab !important; }
[data-bs-theme="light"] .text-warning { color: #a16207 !important; }
[data-bs-theme="light"] .btn-outline-info {
    color: #0a8bab !important; border-color: #0a8bab !important; }
[data-bs-theme="light"] .btn-outline-warning,
[data-bs-theme="light"] .btn-warning {
    color: #854d0e !important; border-color: #d97706 !important; }
/* ④ 亮色语义底（bg-warning 黄 / bg-info 青）上的字：Bootstrap 默认是白字，对比只有
   1.6~2.0；且深色下 L2 会把 .text-dark 提亮成 --sl-text →「黄底浅字」1.32。
   两套主题下这类亮底都配深色字（不分主题，因为 bg-warning/bg-info 在深色下仍是亮块）。
   ⚠️ .bg-light 要单独限定 light：深色下它已被 L2 改成深面板(--sl-surface)，
      字必须继续走 --sl-text（浅），否则深底深字 = 1.11（2026-10-14 踩过）。 */
.badge.bg-warning:not([class*="bg-opacity"]),
.badge.bg-info:not([class*="bg-opacity"]),
.bg-warning.text-dark,
.bg-info.text-dark { color: #1f2937 !important; }
[data-bs-theme="light"] .badge.bg-light,
[data-bs-theme="light"] .bg-light.text-dark { color: #1f2937 !important; }
/* ⚠️ 必须排除 bg-opacity-*：`bg-primary bg-opacity-10 text-primary` 这类徽标（宿舍看板
   状态列就是这么写的）底色是**半透明**的，叠在深底上实际是深色块 —— 再配深字就是
   深底深字（对比 1.01，2026-10-14 实测踩到）。半透明底的徽标交给下一条：深色下提亮字色。 */
[data-bs-theme="dark"] .text-primary { color: #7cb0f7 !important; }
[data-bs-theme="dark"] .text-info { color: #67e8f9 !important; }
[data-bs-theme="dark"] .text-success { color: #34d399 !important; }
[data-bs-theme="dark"] .text-danger { color: #f87171 !important; }
[data-bs-theme="dark"] .text-warning { color: #fbbf24 !important; }
[data-bs-theme="dark"] .text-secondary { color: var(--sl-text-muted) !important; }
/* ⑤ 课表总览「上午/下午」分组列：底色由模板注入的内联 --grp-bg（浅橙/浅蓝），
   不在 L2 兜底清单里 → 深色下亮块 + 浅字（1.08）。按面板色处理。 */
[data-bs-theme="dark"] .ovw-grp-row th,
[data-bs-theme="dark"] th.ovw-grp {
    background: var(--sl-surface-3) !important;
    color: var(--sl-text) !important;
}
/* ⑥ .btn-outline-dark 在深色下仍是 Bootstrap 的深色字面量字 → 深底深字（1.16） */
[data-bs-theme="dark"] .btn-outline-dark {
    color: var(--sl-text) !important;
    border-color: var(--sl-border) !important;
}

/* 打印时永远按浅色输出（成绩单/台账要能打印） */
/* —— 2026-10-14 第三轮审计（UI-M5′）：AI 报告正文（.ai-report-body，AI 生成的 HTML
   含宽表）在移动端把整页撑破（真机实测 /grades/ai 与 /grades/ai/reports 均 +73px）
   → 容器内横滚，等价于给表格加 .table-responsive —— */
.ai-report-body { overflow-x: auto; }
.ai-report-body table { margin-bottom: .5rem; }

/* ========== 动效降级：尊重系统的「减少动态效果」（2026-10-16 第八轮审计 U-05）============
   全站自研动画（床位动效、表格淡入、AI 光标闪烁、查课 fx 系列）此前 0 覆盖
   prefers-reduced-motion —— 前庭障碍用户无法关闭；旧微信 X5 对 steps()/forwards
   的支持度也不一。
   注意用「把时长压到 0.001ms + 迭代 1 次」而不是 animation:none —— .fx-stagger 这类
   「初始 opacity:0 + forwards」的写法，只有动画立即完成才不会永久隐身。
   （theme.css 不含任何 transition/animation 声明，色与动效分层，这里是全局唯一的降级入口）*/
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-delay: 0s !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        transition-delay: 0s !important;
        scroll-behavior: auto !important;
    }
}

@media print {
    :root, [data-bs-theme="dark"] {
        --sl-bg: #fff; --sl-surface: #fff; --sl-surface-2: #fff;
        --sl-surface-3: #f1f5f9; --sl-border: #e2e8f0;
        --sl-text: #000; --sl-text-muted: #333; --sl-text-subtle: #666;
        /* 第七轮审计（U-M6）：表头变量此前未重置（深色下 head=#253149 底 + 浅字）
           ——浏览器默认不打印背景色，深色用户打印成绩单/划线/考务等普通业务表时
           表头浅色文字留在白纸上近乎不可见。补浅色值（与 :root 一致）。 */
        --sl-head-bg: #e7ecf3; --sl-head-bg-2: #f1f4f9;
        --sl-head-text: #334155; --sl-head-border: #d5dde8;
        --sl-head-accent-bg: #cee0e6;
        --sl-th-bg: #f1f4f9; --sl-th-text: #64748b;
    }
    body { background: #fff !important; color: #000 !important; }
}

/* ========== 考试成绩上下文统一页头（2026-10-21 用户口径）==========
   成绩单 / 考务安排 / 数据导入 三页共用同一套页头（app/templates/grades/_exam_head.html）：
   返回按钮 → 页面标题 + 考试名 → 元信息徽标 → 右侧操作区。
   颜色全部走主题变量，浅色 / 深色模式一致。 */
.sl-exam-head {
    border: 1px solid var(--sl-border); border-radius: 12px;
    background: var(--sl-surface); box-shadow: var(--sl-shadow);
}
.sl-exam-head .card-body { padding: .55rem .9rem; }
.sl-exam-back {
    display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; flex: 0 0 auto;
    border: 1px solid var(--sl-border); border-radius: 9px;
    background: var(--sl-surface-2); color: var(--sl-text-muted);
    text-decoration: none; transition: color .12s ease, border-color .12s ease, background-color .12s ease;
}
.sl-exam-back:hover {
    color: var(--sl-sidebar-accent-text); border-color: var(--sl-sidebar-accent);
    background: var(--sl-surface-3);
}
.sl-exam-id { min-width: 0; }
.sl-exam-title {
    display: flex; align-items: center; gap: .42rem;
    font-size: 1.02rem; font-weight: 700; line-height: 1.25; color: var(--sl-text);
}
.sl-exam-title .bi { color: var(--sl-sidebar-accent); }
.sl-exam-name {
    margin-top: 1px; font-size: .78rem; color: var(--sl-text-muted);
    max-width: min(44vw, 520px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sl-exam-meta { display: flex; align-items: center; flex-wrap: wrap; gap: .3rem .55rem; }
.sl-exam-meta .sl-meta-item {
    display: inline-flex; align-items: center; gap: .22rem;
    font-size: .76rem; color: var(--sl-text-muted); white-space: nowrap;
}
.sl-exam-meta .badge { font-weight: 600; }
.sl-exam-actions { min-width: 0; }
.sl-exam-actions .btn { white-space: nowrap; }
@media (max-width: 575.98px) {
    .sl-exam-name { max-width: 60vw; }
    .sl-exam-actions { width: 100%; }
}

/* =============================================================================
   任课教师矩阵（.tm-table）—— 「班级 × 科目 → 任课教师」三处共用一套外观
   -----------------------------------------------------------------------------
   2026-10-28 用户口径：以「成绩分析 → 考务安排 → 核对任课教师」的表格为准，
   「成绩管理 → 任课教师映射」「教务管理 → 任课教师映射」统一到同一份样式。
   要点（都写在这里，模板里不要再复制一遍）：
     · 带边框的密表；表头两行（分组带 + 列名）合成**一块**：同底色、中间只留 1px；
     · 首列（班级）横向冻结，右侧一道分隔阴影；
     · 格内是「透明按钮」——平时看不出框，悬停/聚焦才描边（不是原生下拉的样子）；
     · 容器纵向滚动，表头吸顶（sticky 来自 base.html 的 .table-responsive；
       第 2 行的 top 走 --sl-thead-h，页面脚本按第 1 行真实高度回写）。
   用法：<div class="table-responsive tm-scroll"><table class="table table-sm
   table-bordered align-middle tm-table">…，格子按钮 class="tm-cell"，
   首列加 tm-cls，分组带加 tm-band，班主任列加 tm-head-col。
   ============================================================================= */
.tm-scroll { max-height: 66vh; overflow: auto; }
.tm-table { width: auto; min-width: 100%; }
.tm-table th, .tm-table td { white-space: nowrap; min-width: 96px; }
.tm-scroll .tm-table thead th {
    background: var(--sl-head-bg);
    color: var(--sl-head-text);
    border-color: var(--sl-head-border);
    font-size: .78rem;
    vertical-align: middle;
}
/* 首列（班级）横向冻结：表头那格与第 1 行同色，并压在其它表头之上 */
.tm-scroll .tm-table th.tm-cls,
.tm-scroll .tm-table td.tm-cls {
    position: sticky; left: 0; z-index: 2;
    background: var(--sl-surface);
    box-shadow: 2px 0 4px -2px rgba(15, 30, 61, .25);
    min-width: 62px;
}
.tm-scroll .tm-table thead th.tm-cls { z-index: 4; background: var(--sl-head-bg); }
/* 第 1 行：分组带 */
.tm-table .tm-band { text-align: center; font-weight: 700; letter-spacing: .5px; }
/* 班主任三列（正班 / 副班1 / 副班2）：与学科列表头区分开 */
.tm-table .tm-head-col { background: var(--sl-head-accent-bg); }
/* 两行表头合成一块：第 2 行同底色、去掉重复边框（原来是 bg-2 浅一档 + 上下各一条线，
   分界处像两张表拼在一起） */
.tm-scroll .tm-table thead tr:nth-child(2) th {
    background: var(--sl-head-bg);
    border-top: 0;
}
.tm-scroll .tm-table thead tr:nth-child(2) th.tm-head-col {
    background: var(--sl-head-accent-bg);
}
/* 格内选人位 */
.tm-table .tm-cell {
    width: 100%; border: 1px solid transparent; border-radius: 6px;
    background: transparent; color: var(--sl-text); text-align: left;
    font-size: .8rem; padding: .1rem .3rem;
}
.tm-table .tm-cell:hover, .tm-table .tm-cell:focus {
    border-color: var(--sl-border); background: var(--sl-surface-2); outline: none;
}
.tm-table .tm-cell.empty { color: var(--sl-text-muted); }
/* 学科列表头的「整列填充」（2026-10-28 用户口径：一个老师教多个班，批量应该按**学科列**
   走 —— 把「语文」在所有班都设成同一位老师，而不是把一个班的所有科都设成同一个人）。
   平时淡出，鼠标移到该列表头才显形。 */
.tm-table thead th .tm-colfill {
    border: 0; background: transparent; padding: 0 0 0 2px;
    color: var(--sl-text-muted); opacity: .35; cursor: pointer;
    font-size: .72rem; line-height: 1; vertical-align: middle;
    transition: opacity .12s ease, color .12s ease;
}
.tm-table thead th:hover .tm-colfill { opacity: 1; }
.tm-table thead th .tm-colfill:hover { color: var(--sl-accent); }

/* 2026-11-03 用户反馈：划线矩阵工具栏的「录入形态」下拉文字被截断（只显示"分科（各科分别"），
   看上去和实际不符 —— 给工具栏三个下拉设最小宽度，保证完整显示。 */
#qScope { min-width: 178px; }
#qMode { min-width: 112px; }
#qTpl { min-width: 190px; }
#qScope.q-scope-sel { text-overflow: ellipsis; }
