/* =========================================================
   教导处课务管理台 — 样式表
   Light theme / 打印友好 / 无外部依赖
   ========================================================= */

:root{
  --c-bg:#f4f6fa;
  --c-surface:#ffffff;
  --c-surface-2:#f8fafc;
  --c-border:#e3e8ef;
  --c-border-strong:#cbd5e1;
  --c-text:#1e293b;
  /* 文字色阶（WCAG AA 实测，按「可能出现的底色」取最坏情况）：
     --c-text   #1e293b 白底 14.63:1  科目底色上最低 10.37:1
     --c-text-2 #475569 白底  7.58:1  科目底色上最低  5.37:1  → 课格内文字用它
     --c-text-3 #5b6b7e 白底  5.46:1  全部浅色底（含 #eff6ff/#f1f5f9/#f4f6fa）最低 4.97:1
                 ↑ 不用 #64748b：它在页面底色 #f4f6fa 上只有 4.40:1，会失败
     --c-text-4 #94a3b8 白底  2.56:1  【仅装饰】分隔线、图标底、禁用描边 —— 不得承载文字 */
  --c-text-2:#475569;
  --c-text-3:#5b6b7e;
  --c-text-4:#94a3b8;
  --c-primary:#2563eb;
  --c-primary-dark:#1d4ed8;
  --c-primary-soft:#eff6ff;
  --c-teal:#0d9488;
  --c-teal-soft:#f0fdfa;
  --c-amber:#d97706;
  --c-amber-soft:#fffbeb;
  --c-red:#dc2626;
  --c-red-soft:#fef2f2;
  --c-green:#16a34a;
  --c-green-soft:#f0fdf4;
  --c-purple:#7c3aed;
  --c-purple-soft:#f5f3ff;
  --radius:10px;
  --radius-sm:7px;
  --shadow-1:0 1px 2px rgba(15,23,42,.06),0 1px 3px rgba(15,23,42,.04);
  --shadow-2:0 4px 14px rgba(15,23,42,.08);
  --shadow-3:0 12px 40px rgba(15,23,42,.16);
  --fs:14px;
  /* 全局字体：楷体（用户要求界面全部用楷体）。
     Windows=楷体/KaiTi，macOS=STKaiti/Kaiti SC，最后回退 serif 保证任何系统都有衬线字体 */
  --font-kai:"楷体",KaiTi,"STKaiti","Kaiti SC","BiauKai","TW-Kai","DFKai-SB",serif;
}

*{box-sizing:border-box;}
html,body{height:100%;}
body{
  margin:0;
  /* --font-ui 由「个人中心 → 界面字体」写入；未设置时跟随系统字体
     （2026-10-20 用户要求：默认不再强制楷体） */
  font-family:var(--font-ui,system-ui,-apple-system,"Segoe UI",Roboto,"PingFang SC","Microsoft YaHei","Hiragino Sans GB",sans-serif);
  font-size:var(--fs);
  color:var(--c-text);
  background:var(--c-bg);
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4,p{margin:0;}
button{font-family:inherit;font-size:inherit;}

/* ---------- 键盘焦点可见（WCAG 2.4.7） ----------
   只有键盘操作（Tab / 方向键）才显示焦点环，鼠标点击不显示，避免视觉噪音。
   表单控件已有自己的 focus 环（.field input:focus / input.inp:focus 的 box-shadow），
   这里不再叠一层描边，否则会出现双圈。复选框单独给环。 */
:focus-visible{outline:2px solid var(--c-primary);outline-offset:2px;}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible,
input.inp:focus-visible,select.inp:focus-visible,textarea.inp:focus-visible,
.perf-input:focus-visible{outline:none;}
input[type="checkbox"]:focus-visible,input[type="radio"]:focus-visible{
  outline:2px solid var(--c-primary);outline-offset:2px;
}
/* 弹窗容器用 tabindex="-1" 承接焦点，聚焦时不要显示描边 */
.modal:focus{outline:none;}

/* ---------- 无障碍整改（2026-10-19，WCAG 2.2 AA） ---------- */
/* 2.4.1 绕过区块：跳过导航直达主内容（键盘第一个 Tab 可见） */
.skip-link{
  position:fixed;left:50%;top:-60px;transform:translateX(-50%);z-index:3000;
  background:var(--c-primary);color:#fff;padding:10px 20px;border-radius:0 0 var(--radius-sm) var(--radius-sm);
  font-size:14px;font-weight:600;text-decoration:none;box-shadow:var(--shadow-2);
  transition:top .18s ease;
}
.skip-link:focus{top:0;}
/* 主内容区承接切页焦点：不显示描边，但本身可被聚焦（tabindex="-1"） */
#pageRoot:focus{outline:none;}
/* 2.4.7 焦点可见：可滚动区域（表格容器，2026-10-19 起可 Tab 聚焦）的焦点环，
   overflow:auto 会裁掉 outline → 用内缩 box-shadow，任何底色上都看得见 */
.table-wrap:focus-visible,.cls-tbl-wrap:focus-visible{
  outline:none;
  box-shadow:inset 0 0 0 2px var(--c-primary);
}
/* 2.4.11 焦点不被遮挡：课表格子键盘聚焦时给内缩高亮（格子底色是科目色，外描边会糊） */
.cell:focus-visible,.cell:focus{
  outline:none;
  box-shadow:inset 0 0 0 3px var(--c-primary);
}
/* 2.5.8 目标尺寸（最小 24×24）：可点击的小标签/页签 */
.tabs .tab,.chip,.cls-hide,.restore-chip{min-height:24px;}
/* 4.1.2 状态可感知：禁用按钮统一观感（配合 JS 的 disabled + aria-disabled） */
button:disabled{cursor:not-allowed;}
.page-readonly button:disabled{opacity:.45;}
/* 2.3.3 动画减弱：用户系统开了"减少动态效果"时，过渡一律关掉 */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important;
  }
}
input,select,textarea{font-family:inherit;font-size:inherit;color:inherit;}
a{color:var(--c-primary);}
.muted{color:var(--c-text-2);}
.tiny{font-size:12px;}
.hidden,[hidden]{display:none !important;}
.mt8{margin-top:8px;} .mt12{margin-top:12px;} .mt16{margin-top:16px;} .mt24{margin-top:24px;}
.mb8{margin-bottom:8px;} .mb12{margin-bottom:12px;} .mb16{margin-bottom:16px;}
.row{display:flex;gap:10px;align-items:center;}
.row-wrap{display:flex;gap:10px;align-items:center;flex-wrap:wrap;}
.spacer{flex:1;}
.grow{flex:1;min-width:0;}
.nowrap{white-space:nowrap;}
.right{text-align:right;}
.center{text-align:center;}

/* ---------- 登录页 ---------- */
.login-wrap{
  min-height:100vh;display:flex;align-items:center;justify-content:center;
  background:linear-gradient(140deg,#eef4ff 0%,#f7fbff 45%,#eafaf6 100%);
  padding:24px;
}
.login-card{
  width:100%;max-width:400px;background:var(--c-surface);border-radius:16px;
  box-shadow:var(--shadow-3);padding:34px 30px 22px;border:1px solid rgba(255,255,255,.8);
}
.login-brand{display:flex;flex-direction:column;gap:10px;align-items:center;
  text-align:center;margin-bottom:22px;}
/* 校名标识图（2026-10-16 用户提供「学校.png」替换原“课”字方块） */
.login-logo-img{width:100%;max-width:400px;height:auto;display:block;
  object-fit:contain;user-select:none;-webkit-user-drag:none;}
.login-brand h1{font-size:18px;font-weight:700;letter-spacing:.4px;}
.login-brand p{font-size:12.5px;margin-top:3px;}
/* 仅供读屏/脚本使用的隐藏文本（2026-10-16 起校名、学期、平台名都不再显示） */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;}
.login-logo{
  width:46px;height:46px;border-radius:13px;flex:none;
  background:linear-gradient(135deg,var(--c-primary),#0ea5e9);
  color:#fff;display:flex;align-items:center;justify-content:center;
  font-size:21px;font-weight:700;letter-spacing:1px;
}
.login-brand h1{font-size:18px;font-weight:700;letter-spacing:.4px;}
.login-brand p{font-size:12.5px;margin-top:3px;}
.login-form{display:flex;flex-direction:column;gap:15px;}
.field{display:flex;flex-direction:column;gap:6px;}
.field-label{font-size:12.5px;color:var(--c-text-2);font-weight:500;}
.field input,.field select,.field textarea{
  height:38px;padding:0 12px;border:1px solid var(--c-border-strong);
  border-radius:var(--radius-sm);background:#fff;outline:none;transition:.15s;
}
.field textarea{height:auto;padding:9px 12px;resize:vertical;min-height:70px;line-height:1.6;}
.field input:focus,.field select:focus,.field textarea:focus{
  border-color:var(--c-primary);box-shadow:0 0 0 3px rgba(37,99,235,.13);
}
.login-error{
  background:var(--c-red-soft);color:var(--c-red);border:1px solid #fecaca;
  padding:9px 12px;border-radius:var(--radius-sm);font-size:13px;
}
/* 登录页账号提示：楷体、关键词加粗、无边框（2026-10-20 用户要求，与设计稿一致）
   这段"说话"的文字固定用楷体，不跟随系统字体，保持学校的那股味道 */
.login-hint{
  margin:12px 0 0;font-size:15.5px;line-height:2;color:var(--c-text);
  font-family:var(--font-kai);text-align:left;
}
.login-hint b{color:var(--c-text);font-weight:700;}
/* 登录页底部的学期与教学周：自动更新（2026-10-20 用户要求） */
.login-term{
  margin:18px 0 2px;text-align:center;font-size:13px;color:var(--c-text-2);
  font-family:var(--font-kai);letter-spacing:.4px;
}
.login-term[hidden]{display:none;}
.login-tip{
  margin-top:16px;font-size:12.5px;color:var(--c-text-2);line-height:1.9;
  background:var(--c-surface-2);border:1px dashed var(--c-border-strong);
  border-radius:var(--radius-sm);padding:10px 12px;
}
.login-tip b{color:var(--c-text);}
.login-tip[hidden]{display:none;}
/* 登录页的本地数据入口（.login-seed「载入本校课表」/ .login-foot「演示数据·从备份恢复」）
   与 .login-mode-switch（单机 / 在线共享切换）已随单机模式一并移除：
   2026-10-13 起只有云端登录一种方式，数据以云端为唯一准绳。 */
.or-line{
  position:relative;text-align:center;margin:16px 0 12px;
  font-size:12px;color:var(--c-text-3);
}
.or-line::before{
  content:'';position:absolute;left:0;right:0;top:50%;height:1px;background:var(--c-border);
}
.or-line span{position:relative;background:#fff;padding:0 10px;}
/* 验证码输入区 */
.otp-panel{
  margin-top:14px;padding:14px;border:1px solid var(--c-primary-soft,#bfdbfe);
  border-radius:8px;background:var(--c-primary-soft,#eff6ff);
}
.otp-tip{
  font-size:12.5px;color:var(--c-text-2);line-height:1.9;margin-bottom:10px;
}
.otp-tip .link-btn{font-size:12.5px;margin-left:8px;}
.login-ok{
  margin-top:12px;padding:9px 12px;border-radius:6px;font-size:12.5px;line-height:1.7;
  background:#ecfdf5;color:#047857;border:1px solid #a7f3d0;
}
.link-btn{
  background:none;border:none;color:var(--c-primary);cursor:pointer;
  padding:2px 4px;font-size:12.5px;border-radius:4px;
}
.link-btn:hover{background:var(--c-primary-soft);}
.dot-sep{color:var(--c-text-3);}

/* ---------- 应用框架 ---------- */
/* 背景层（2026-10-16 用户要求：登录后界面用校园照片做背景，可在个人中心更换/调虚化）
   实现要点：
   ① 背景是 #appView 里独立的一层 .app-bg，放在 .sidebar / .main 之下（z-index:0/1），
      所以不用改任何页面结构，也不会被卡片盖住整块看不见；
   ② 模糊用 filter: blur()。模糊会把边缘吸掉，所以图片层四周各外扩 30px（inset:-30px），
      再由 .app-bg 自己 overflow:hidden 裁掉，边缘不会出现透明缝；
   ③ 模糊越大越吃显存，滑块上限给到 16px，够用又不至于卡；
   ④ --app-bg-veil 是白色蒙版浓度：底图越花越要压，保证表格文字对比度。 */
.app{position:relative;overflow:hidden;}
.app-bg{position:absolute;inset:0;z-index:0;overflow:hidden;pointer-events:none;}
.app-bg::before{
  content:'';position:absolute;left:-30px;right:-30px;top:-30px;bottom:-30px;
  background-image:var(--app-bg-image,none);
  background-size:cover;background-position:center;background-repeat:no-repeat;
  filter:blur(var(--app-bg-blur,6px));
  transform:translateZ(0);
}
.app-bg::after{
  content:'';position:absolute;inset:0;
  background:rgba(255,255,255,var(--app-bg-veil,.58));
}
/* 关掉背景时（--app-bg-image:none）把两层都撤掉，退回纯色页背景 */
html[data-appbg="off"] .app-bg{display:none;}
/* 侧栏与顶栏在有背景时改半透明，让背景透出来但文字仍清晰 */
html[data-appbg="on"] .sidebar{background:rgba(255,255,255,var(--app-bg-panel,.86));backdrop-filter:blur(3px);}
html[data-appbg="on"] .topbar{background:rgba(255,255,255,var(--app-bg-panel,.86));backdrop-filter:blur(3px);}
.sidebar,.main{position:relative;z-index:1;}

/* ---------- 内容区白底浓度（2026-10-19 用户要求） ----------
   截图反馈：卡片和表格那层纯白把照片背景遮得一点不剩。
   新增 --app-bg-panel（内容区白底浓度，默认 86%，可在「个人中心 → 界面背景」拖滑块调）：
   所有会盖住背景的大面积白面（卡片、指标卡、表格、表头）都改成同一浓度，
   调低就能透出背景； veil（背景淡化）负责压底图本身，两者叠加仍要保证文字看得清。 */
html[data-appbg="on"] .card{background:rgba(255,255,255,var(--app-bg-panel,.86));}
html[data-appbg="on"] .stat{background:rgba(255,255,255,var(--app-bg-panel,.86));}
html[data-appbg="on"] table.tbl{background:rgba(255,255,255,var(--app-bg-panel,.86));}
html[data-appbg="on"] table.tbl th{background:rgba(248,250,252,var(--app-bg-panel,.86));}
/* 表格行 hover 仍要能看出来：在白底之上再叠一层浅色 */
html[data-appbg="on"] table.tbl tbody tr:hover{background:rgba(241,245,249,.75);}
/* 弹窗/浮层不跟着变（它们是临时操作面，保持不透明白，免得背景花里胡哨干扰填写） */

/* ---------- 登录页背景 ----------
   2026-10-16 用户要求：上传的背景图登录界面也要看得到（此前只有登录后的主界面有）。
   复用同一套 CSS 变量（--app-bg-image / --app-bg-blur / --app-bg-veil）：
   设置里换图、拉虚化，登录页和主界面一起变，不需要额外存一份。
   登录卡片本身仍是不透明白，背景从卡片四周透出来；关掉背景时两层撤掉、退回原渐变。 */
.login-wrap{position:relative;overflow:hidden;}
.login-wrap::before{
  content:'';position:absolute;left:-30px;right:-30px;top:-30px;bottom:-30px;z-index:0;
  background-image:var(--app-bg-image,none);
  background-size:cover;background-position:center;background-repeat:no-repeat;
  filter:blur(var(--app-bg-blur,6px));transform:translateZ(0);
}
.login-wrap::after{
  content:'';position:absolute;inset:0;z-index:0;
  background:rgba(255,255,255,var(--app-bg-veil,.58));
}
.login-wrap > *{position:relative;z-index:1;}
html[data-appbg="off"] .login-wrap::before,
html[data-appbg="off"] .login-wrap::after{display:none;}

.app{display:flex;height:100vh;overflow:hidden;}
.sidebar{
  width:212px;flex:none;background:#fff;border-right:1px solid var(--c-border);
  display:flex;flex-direction:column;
}
.side-brand{display:flex;gap:10px;align-items:center;padding:16px 16px 14px;}
/* 2026-10-19：「课」字方块换成学校校徽（透明 PNG）。
   去掉渐变底与文字样式，只留尺寸；contain 保证圆形徽章不变形。 */
.side-logo{
  width:32px;height:32px;flex:none;object-fit:contain;
}
.side-brand-text{display:flex;flex-direction:column;min-width:0;}
.side-brand-text strong{font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.side-brand-text span{font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.side-nav{flex:1;overflow-y:auto;padding:6px 10px 12px;}
.nav-group-title{
  font-size:11px;color:var(--c-text-3);font-weight:600;letter-spacing:.6px;
  padding:14px 8px 6px;
}
.nav-item{
  display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:8px;
  color:var(--c-text);cursor:pointer;font-size:13.5px;margin-bottom:2px;
  border:none;background:none;width:100%;text-align:left;transition:.13s;
}
.nav-item:hover{background:var(--c-surface-2);}
.nav-item.active{background:var(--c-primary-soft);color:var(--c-primary-dark);font-weight:600;}
.nav-ico{width:17px;text-align:center;font-size:14px;flex:none;opacity:.85;}
.nav-badge{
  margin-left:auto;background:var(--c-red);color:#fff;font-size:11px;
  padding:1px 6px;border-radius:9px;font-weight:600;
}
.side-foot{padding:12px;border-top:1px solid var(--c-border);}
.side-user{display:flex;gap:9px;align-items:center;margin-bottom:9px;padding:0 2px;}
.avatar{
  width:32px;height:32px;border-radius:50%;background:var(--c-primary-soft);
  color:var(--c-primary-dark);display:flex;align-items:center;justify-content:center;
  font-weight:600;font-size:13px;flex:none;
}
.side-user-text{display:flex;flex-direction:column;min-width:0;}
.side-user-text strong{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.side-user-text span{font-size:11px;}

.main{flex:1;display:flex;flex-direction:column;min-width:0;overflow:hidden;}
.topbar{
  height:56px;flex:none;background:#fff;border-bottom:1px solid var(--c-border);
  display:flex;align-items:center;padding:0 20px;gap:14px;
}
.topbar-left{display:flex;align-items:baseline;gap:10px;min-width:0;}
.topbar-left h2{font-size:16px;font-weight:700;white-space:nowrap;}
.topbar-left span{font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.topbar-right{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap;}
/* 移动端导航开关：宽屏隐藏，只在 ≤860px 出现（见下方响应式段） */
.nav-toggle{
  display:none;align-items:center;justify-content:center;flex:none;
  width:34px;height:34px;border-radius:var(--radius-sm);
  border:1px solid var(--c-border-strong);background:#fff;color:var(--c-text);
  font-size:15px;line-height:1;cursor:pointer;transition:.13s;
}
.nav-toggle:hover{background:var(--c-surface-2);}
.nav-toggle[aria-expanded="true"]{background:var(--c-primary-soft);border-color:var(--c-primary);color:var(--c-primary-dark);}
/* 抽屉遮罩：点空白处关闭侧栏 */
.nav-mask{
  position:fixed;left:0;right:0;top:0;bottom:0;
  background:rgba(15,23,42,.42);z-index:890;
}
.nav-mask[hidden]{display:none;}
.page{flex:1;overflow-y:auto;padding:18px 20px 40px;}

/* ---------- 卡片 ---------- */
.card{
  background:var(--c-surface);border:1px solid var(--c-border);
  border-radius:var(--radius);box-shadow:var(--shadow-1);margin-bottom:16px;
}
.card-head{
  display:flex;align-items:center;gap:10px;padding:13px 16px;
  border-bottom:1px solid var(--c-border);flex-wrap:wrap;
}
.card-head h3{font-size:14px;font-weight:700;}
.card-head .sub{font-size:12px;color:var(--c-text-2);}
.card-body{padding:16px;}
.card-body.tight{padding:0;}
.card-body.pad-sm{padding:12px;}

.stat-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:14px;}
.stat{
  background:#fff;border:1px solid var(--c-border);border-radius:var(--radius);
  padding:15px 16px;box-shadow:var(--shadow-1);position:relative;overflow:hidden;
}
.stat::after{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--c-primary);opacity:.9;}
.stat.t-teal::after{background:var(--c-teal);}
.stat.t-amber::after{background:var(--c-amber);}
.stat.t-red::after{background:var(--c-red);}
.stat.t-purple::after{background:var(--c-purple);}
.stat .k{font-size:12.5px;color:var(--c-text-2);margin-bottom:7px;}
.stat .v{font-size:24px;font-weight:700;letter-spacing:.5px;}
.stat .v small{font-size:12px;font-weight:500;color:var(--c-text-2);margin-left:3px;}

/* ---------- 按钮 ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  height:32px;padding:0 13px;border-radius:var(--radius-sm);
  border:1px solid var(--c-border-strong);background:#fff;color:var(--c-text);
  cursor:pointer;font-size:13px;transition:.13s;white-space:nowrap;
}
.btn:hover{background:var(--c-surface-2);border-color:var(--c-text-3);}
.btn:active{transform:translateY(1px);}
.btn-primary{background:var(--c-primary);border-color:var(--c-primary);color:#fff;}
.btn-primary:hover{background:var(--c-primary-dark);border-color:var(--c-primary-dark);}
.btn-danger{background:var(--c-red);border-color:var(--c-red);color:#fff;}
.btn-danger:hover{background:#b91c1c;border-color:#b91c1c;}
.btn-teal{background:var(--c-teal);border-color:var(--c-teal);color:#fff;}
.btn-teal:hover{background:#0f766e;border-color:#0f766e;}
.btn-ghost{background:transparent;border-color:transparent;color:var(--c-text-2);}
.btn-ghost:hover{background:var(--c-surface-2);color:var(--c-text);}
/* 需要先完成前置操作才能生效的按钮（如未连云端时的上传） */
.btn-warn{background:#fffbeb;border-color:#fcd34d;color:#b45309;}
.btn-warn:hover{background:#fef3c7;border-color:#fbbf24;color:#92400e;}
.btn-sm{height:27px;padding:0 9px;font-size:12.5px;}
.btn-block{width:100%;}
.btn[disabled]{opacity:.5;cursor:not-allowed;}
.btn-group{display:inline-flex;border:1px solid var(--c-border-strong);border-radius:var(--radius-sm);overflow:hidden;}
.btn-group .btn{border:none;border-radius:0;border-right:1px solid var(--c-border);}
.btn-group .btn:last-child{border-right:none;}
.btn-group .btn.active{background:var(--c-primary);color:#fff;}

/* ---------- 表格 ---------- */
.table-wrap{overflow-x:auto;}
table.tbl{width:100%;border-collapse:collapse;font-size:13px;}
table.tbl th{
  text-align:left;padding:10px 12px;background:var(--c-surface-2);
  border-bottom:1px solid var(--c-border);font-weight:600;color:var(--c-text-2);
  font-size:12.5px;white-space:nowrap;position:sticky;top:0;z-index:2;
}
table.tbl td{padding:9px 12px;border-bottom:1px solid var(--c-border);vertical-align:middle;}
table.tbl tbody tr:hover{background:#fbfcfe;}
table.tbl tbody tr:last-child td{border-bottom:none;}
.empty{padding:40px 20px;text-align:center;color:var(--c-text-3);font-size:13.5px;}
.empty-ico{font-size:32px;display:block;margin-bottom:8px;opacity:.5;}

/* ---------- 标签/徽章 ---------- */
.badge{
  display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:20px;
  font-size:11.5px;font-weight:600;background:var(--c-surface-2);color:var(--c-text-2);
  border:1px solid var(--c-border);white-space:nowrap;
}
.badge.b-blue{background:var(--c-primary-soft);color:var(--c-primary-dark);border-color:#bfdbfe;}
.badge.b-teal{background:var(--c-teal-soft);color:#0f766e;border-color:#99f6e4;}
.badge.b-amber{background:var(--c-amber-soft);color:#b45309;border-color:#fde68a;}
.badge.b-red{background:var(--c-red-soft);color:#b91c1c;border-color:#fecaca;}
.badge.b-green{background:var(--c-green-soft);color:#15803d;border-color:#bbf7d0;}
.badge.b-purple{background:var(--c-purple-soft);color:#6d28d9;border-color:#ddd6fe;}
.badge.b-gray{background:#f1f5f9;color:#4b5563;border-color:#e2e8f0;}   /* 2026-10-19：#64748b 只有 4.34:1，改 #4b5563 = 6.90:1 */
.chip{
  display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:7px;
  font-size:12.5px;background:var(--c-surface-2);border:1px solid var(--c-border);
}
.chip .x{cursor:pointer;color:var(--c-text-3);font-size:14px;line-height:1;}
.chip .x:hover{color:var(--c-red);}
.chip-list{display:flex;gap:6px;flex-wrap:wrap;}
/* 可点的 chip（2026-10-20：早读弹窗里按年级给出的快捷教师标签） */
.chip-btn{cursor:pointer;font-family:inherit;font-size:12.5px;color:var(--c-text);line-height:1.5;transition:background .12s,border-color .12s;}
.chip-btn:hover{background:var(--c-primary-soft);border-color:var(--c-primary);color:var(--c-primary-dark);}
.chip-btn:focus-visible{outline:2px solid var(--c-primary);outline-offset:2px;}

/* ---------- 课表网格 ---------- */
.sch-wrap{overflow-x:auto;border-radius:var(--radius-sm);}
table.sch{border-collapse:separate;border-spacing:0;width:100%;min-width:760px;font-size:12.5px;}
table.sch th{
  background:var(--c-surface-2);font-weight:600;color:var(--c-text-2);
  padding:8px 6px;border-bottom:1px solid var(--c-border);border-right:1px solid var(--c-border);
  font-size:12px;text-align:center;position:sticky;top:0;z-index:2;
}
table.sch th:last-child,table.sch td:last-child{border-right:none;}
table.sch th.corner{left:0;z-index:3;}
table.sch td{
  border-bottom:1px solid var(--c-border);border-right:1px solid var(--c-border);
  padding:3px;vertical-align:top;height:62px;min-width:96px;
}
table.sch td.period-col{
  background:var(--c-surface-2);text-align:center;vertical-align:middle;padding:4px 8px;
  min-width:78px;position:sticky;left:0;z-index:1;
}
.period-name{font-weight:600;font-size:12.5px;display:block;}
.period-time{font-size:11px;color:var(--c-text-3);display:block;margin-top:2px;}
.cell{
  border-radius:6px;padding:5px 7px;height:100%;min-height:54px;
  display:flex;flex-direction:column;gap:2px;justify-content:center;
  cursor:pointer;transition:.13s;border:1px solid transparent;position:relative;
}
.cell:hover{filter:brightness(.97);border-color:var(--c-border-strong);}
.cell .c-sub{font-weight:600;font-size:12.5px;line-height:1.25;}
.cell .c-cls{font-weight:600;font-size:11.5px;line-height:1.25;color:var(--c-text-2);}
.cell .c-tea{font-size:11.5px;color:var(--c-text-2);line-height:1.25;}
.cell .c-room{font-size:11px;color:var(--c-text-2);}   /* 坐在科目底色上，必须用二级色才达 4.5:1 */
.cell.empty-cell{
  border:1px dashed var(--c-border-strong);background:#fcfdff;
  align-items:center;justify-content:center;color:var(--c-text-3);font-size:16px;
}
.cell.empty-cell:hover{background:var(--c-primary-soft);color:var(--c-primary);border-color:var(--c-primary);}
.cell.canceled{opacity:.55;text-decoration:line-through;}
.cell .c-flag{
  position:absolute;top:3px;right:4px;font-size:10px;padding:0 4px;border-radius:4px;
  /* 2026-10-19 对比度整改：白字 on #d97706 仅 3.19:1、on #0d9488 3.74:1，
     改深底后 5.02:1 / 5.47:1（紫 #7c3aed 5.70 原已达标，不动） */
  background:#b45309;color:#fff;font-weight:600;line-height:15px;
}
.cell .c-flag.f-sub{background:#0f766e;}
.cell .c-flag.f-move{background:#7c3aed;}

/* 课表搜索：命中高亮 / 未命中淡化 / 列淡化 */
.cell.hit{
  box-shadow:0 0 0 2px #2563eb,0 2px 8px rgba(37,99,235,.18);
  border-radius:6px;
}
.cell.dim{opacity:.3;filter:grayscale(.5);}
table.sch td.col-dim{opacity:.32;}
table.sch th.col-dim{color:var(--c-text-3);text-decoration:line-through;}
tr.row-hit td{background:#eff6ff;}

/* 搜索结果列表 */
.search-empty{padding:18px 16px;text-align:center;color:var(--c-text-3);font-size:13px;}

.term-picker{display:inline-flex;align-items:center;gap:6px;}

/* 绩效表内联编辑 */
.perf-input{width:66px;text-align:center;padding:0 6px;}
.perf-input:focus{box-shadow:0 0 0 2px rgba(37,99,235,.25);}
td .perf-input + .perf-input{margin-left:2px;}

/* 作息节次：课表显示开关 */
.inline-check{display:inline-flex;align-items:center;gap:6px;cursor:pointer;font-size:12.5px;white-space:nowrap;}
.inline-check input{width:15px;height:15px;cursor:pointer;accent-color:var(--c-primary);}
tr.row-dim td{opacity:.55;}
tr.row-dim .inline-check span{color:var(--c-text-3);}
.res-list{display:flex;flex-direction:column;}
.res-item{
  display:flex;align-items:center;gap:9px;padding:8px 16px;
  border-bottom:1px solid var(--c-border);cursor:pointer;transition:.12s;font-size:12.5px;
}
.res-item:last-child{border-bottom:none;}
.res-item:hover{background:var(--c-primary-soft);}
.res-item.current{background:#f0fdf4;}
.res-when{color:var(--c-text-2);white-space:nowrap;min-width:96px;font-variant-numeric:tabular-nums;}
.res-cls{font-weight:600;white-space:nowrap;}
.res-tea{color:var(--c-text-2);white-space:nowrap;}
.res-tags{display:flex;gap:5px;}
.res-tag{font-size:11px;color:var(--c-text-3);}
.res-tag-hide{color:#b45309;background:#fef3c7;border-radius:4px;padding:0 5px;}
.res-teacher-item{gap:10px;}
.res-tea-name{font-weight:600;min-width:78px;}
.res-preview{color:var(--c-text-2);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

.legend{display:flex;gap:14px;flex-wrap:wrap;font-size:12px;color:var(--c-text-2);align-items:center;}
.legend i{display:inline-block;width:11px;height:11px;border-radius:3px;margin-right:5px;vertical-align:-1px;}

/* 空闲矩阵 */
table.free{border-collapse:separate;border-spacing:0;width:100%;min-width:640px;}
table.free th{
  background:var(--c-surface-2);padding:8px;font-size:12px;color:var(--c-text-2);
  border-bottom:1px solid var(--c-border);text-align:center;font-weight:600;
}
table.free td{border-bottom:1px solid var(--c-border);padding:0;text-align:center;height:36px;}
table.free td.name{
  text-align:left;padding:6px 10px;font-size:12.5px;font-weight:600;background:var(--c-surface-2);
  position:sticky;left:0;white-space:nowrap;
}
.slot-cell{display:flex;align-items:center;justify-content:center;height:36px;font-size:11.5px;font-weight:600;}
.slot-free{background:var(--c-green-soft);color:#15803d;}
/* 空闲时间表的中值格（有安排显示班级，无安排留白） */
.slot-mid{background:var(--c-amber-soft);color:#92400e;font-weight:600;}
/* 早读格（2026-10-20）：浅蓝，与课表早读行同一视觉语言 */
.slot-early{background:#eef4fb;color:#1d4ed8;font-weight:600;}
/* 空闲时间表的社团格：延时一 / 延时二 这类「不计课时」的节次，
   实际是各科社团开课的时间段 —— 周五开设社团的老师这里显示社团名（2026-10-16 用户要求）。
   用紫色以便与中值（琥珀）、上课（灰蓝）一眼区分开。 */
.slot-club{background:var(--c-purple-soft);color:#6d28d9;font-weight:600;}
.slot-club small{display:block;font-size:9.5px;font-weight:400;opacity:.85;}
/* 空闲时间的颜色开关：关掉后状态底色全部变白，靠文字区分 */
.ft-wrap.no-color .slot-cell{background:#ffffff !important;color:#1f2937 !important;}
/* 打印课表：列等宽（节次 16% + 各天均分），空课的列不再被压窄 */
.print-doc table.p-sch{table-layout:fixed;width:100%;}
.slot-busy{background:#eef2f7;color:#94a3b8;}
.slot-leave{background:var(--c-red-soft);color:#b91c1c;}
.slot-off{background:#f1f5f9;color:#cbd5e1;}
.slot-sub{background:var(--c-primary-soft);color:var(--c-primary-dark);}

/* ---------- 工具栏 ---------- */
.toolbar{
  display:flex;gap:9px;align-items:center;flex-wrap:wrap;
  padding:12px 16px;border-bottom:1px solid var(--c-border);background:#fff;
}
.toolbar .grow{flex:1;}
input.inp,select.inp,textarea.inp{
  height:32px;padding:0 10px;border:1px solid var(--c-border-strong);
  border-radius:var(--radius-sm);background:#fff;outline:none;transition:.13s;min-width:0;
}
textarea.inp{height:auto;padding:8px 10px;min-height:70px;resize:vertical;line-height:1.6;}
select.inp{padding-right:24px;cursor:pointer;}
input.inp:focus,select.inp:focus,textarea.inp:focus{
  border-color:var(--c-primary);box-shadow:0 0 0 3px rgba(37,99,235,.12);
}
input.inp::placeholder,textarea.inp::placeholder{color:var(--c-text-3);}
.inp-sm{height:27px;font-size:12.5px;padding:0 8px;}
.search{position:relative;}
.search input{padding-left:28px;}
.search::before{content:"🔍";position:absolute;left:9px;top:50%;transform:translateY(-50%);font-size:12px;opacity:.5;}

/* ---------- 弹窗 ---------- */
.modal-mask{
  position:fixed;inset:0;background:rgba(15,23,42,.45);z-index:1000;
  display:flex;align-items:flex-start;justify-content:center;
  padding:40px 16px;overflow-y:auto;animation:fadeIn .14s ease;
}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
.modal{
  background:#fff;border-radius:14px;box-shadow:var(--shadow-3);
  width:100%;max-width:560px;animation:popIn .18s ease;margin:auto;
}
@keyframes popIn{from{transform:translateY(10px) scale(.985);opacity:0}to{transform:none;opacity:1}}
.modal.wide{max-width:820px;}
.modal.xwide{max-width:1080px;}
.modal-head{
  display:flex;align-items:center;gap:10px;padding:16px 20px;
  border-bottom:1px solid var(--c-border);
}
.modal-head h3{font-size:15px;font-weight:700;flex:1;}
.modal-close{
  border:none;background:none;font-size:20px;color:var(--c-text-3);
  cursor:pointer;line-height:1;padding:2px 4px;border-radius:6px;
}
.modal-close:hover{background:var(--c-surface-2);color:var(--c-text);}
.modal-body{padding:20px;max-height:calc(100vh - 220px);overflow-y:auto;}
.modal-foot{
  display:flex;justify-content:flex-end;gap:9px;padding:14px 20px;
  border-top:1px solid var(--c-border);background:var(--c-surface-2);
  border-radius:0 0 14px 14px;
}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;}
.form-grid .full{grid-column:1 / -1;}
.form-section-title{
  font-size:12px;font-weight:700;color:var(--c-text-2);letter-spacing:.5px;
  padding-bottom:8px;border-bottom:1px solid var(--c-border);margin-bottom:14px;
}
.hint{font-size:12px;color:var(--c-text-3);line-height:1.7;}

/* ---------- Toast ---------- */
.toast-root{position:fixed;top:18px;right:18px;z-index:2000;display:flex;flex-direction:column;gap:9px;}
.toast{
  background:#fff;border:1px solid var(--c-border);border-left:3px solid var(--c-primary);
  border-radius:var(--radius-sm);box-shadow:var(--shadow-2);padding:11px 15px;
  font-size:13px;min-width:230px;max-width:400px;animation:slideIn .2s ease;
  display:flex;gap:8px;align-items:flex-start;
}
@keyframes slideIn{from{transform:translateX(24px);opacity:0}to{transform:none;opacity:1}}
.toast.ok{border-left-color:var(--c-green);}
.toast.err{border-left-color:var(--c-red);}
.toast.warn{border-left-color:var(--c-amber);}
.toast .t-ico{font-size:14px;line-height:1.4;}
.toast.out{animation:slideOut .2s ease forwards;}
@keyframes slideOut{to{transform:translateX(24px);opacity:0}}

/* ---------- 冲突提示 ---------- */
.alert{
  border-radius:var(--radius-sm);padding:11px 14px;font-size:13px;line-height:1.7;
  border:1px solid;margin-bottom:12px;
}
.alert-warn{background:var(--c-amber-soft);border-color:#fde68a;color:#92400e;}
.alert-err{background:var(--c-red-soft);border-color:#fecaca;color:#991b1b;}
.alert-info{background:var(--c-primary-soft);border-color:#bfdbfe;color:#1e40af;}
.alert-ok{background:var(--c-green-soft);border-color:#bbf7d0;color:#166534;}
.alert ul{margin:6px 0 0;padding-left:20px;}
.alert li{margin:2px 0;}

/* ---------- 分步向导 ---------- */
.steps{display:flex;gap:0;margin-bottom:20px;}
.step{flex:1;text-align:center;position:relative;padding-bottom:12px;}
.step::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--c-border);
}
.step.done::after,.step.active::after{background:var(--c-primary);}
.step .s-no{
  width:22px;height:22px;border-radius:50%;background:var(--c-border);color:#fff;
  display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;
  margin-bottom:5px;
}
.step.done .s-no{background:var(--c-green);}
.step.active .s-no{background:var(--c-primary);}
.step .s-name{display:block;font-size:12px;color:var(--c-text-2);}
.step.active .s-name{color:var(--c-primary-dark);font-weight:600;}

/* ---------- 列表项 ---------- */
.list{display:flex;flex-direction:column;}
.list-item{
  display:flex;gap:12px;align-items:center;padding:12px 16px;
  border-bottom:1px solid var(--c-border);
}
.list-item:last-child{border-bottom:none;}
.list-item:hover{background:#fbfcfe;}
.li-main{flex:1;min-width:0;}
.li-title{font-size:13.5px;font-weight:600;margin-bottom:3px;}
.li-desc{font-size:12px;color:var(--c-text-2);line-height:1.6;}
.li-actions{display:flex;gap:6px;flex-wrap:wrap;}
/* 社团管理：成员人数 / 容量 直接在表格里填（不用进编辑窗） */
.mem-cell{display:flex;align-items:center;gap:4px;flex-wrap:wrap;}
.mem-cell .cell-num{width:64px;padding:4px 6px;text-align:center;font-size:12.5px;}
.mem-cell .mem-sep{color:var(--c-text-3);}
.mem-cell .mem-unit{font-size:12px;color:var(--c-text-2);}

/* ---------- 子标签页 ---------- */
/* 标签栏：窄屏标签多时横向滚动，不压缩、不换行（原先 5 个子标签在手机上会被裁掉） */
.tabs{
  display:flex;gap:2px;border-bottom:1px solid var(--c-border);padding:0 16px;background:#fff;
  overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;
}
.tabs::-webkit-scrollbar{display:none;}
.tab{
  padding:11px 14px;font-size:13.5px;color:var(--c-text-2);cursor:pointer;
  border:none;background:none;border-bottom:2px solid transparent;margin-bottom:-1px;
  flex:none;white-space:nowrap;
}
.tab:hover{color:var(--c-text);}
.tab.active{color:var(--c-primary-dark);border-bottom-color:var(--c-primary);font-weight:600;}
.tab .cnt{
  font-size:11px;background:var(--c-surface-2);border-radius:8px;padding:0 6px;margin-left:5px;
  color:var(--c-text-2);
}
.tab.active .cnt{background:var(--c-primary-soft);color:var(--c-primary-dark);}

/* ---------- 课表编辑单元格选择器 ---------- */
.picker-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:8px;max-height:280px;overflow-y:auto;padding:2px;}
.picker-item{
  border:1px solid var(--c-border);border-radius:8px;padding:9px 10px;cursor:pointer;
  background:#fff;text-align:left;transition:.13s;
}
.picker-item:hover{border-color:var(--c-primary);background:var(--c-primary-soft);}
.picker-item.sel{border-color:var(--c-primary);background:var(--c-primary-soft);box-shadow:0 0 0 2px rgba(37,99,235,.15);}
.picker-item .p-name{font-size:13px;font-weight:600;}
.picker-item .p-sub{font-size:11.5px;color:var(--c-text-2);margin-top:2px;}

/* ---------- 打印 ---------- */
.print-root{display:none;}
.print-doc{font-family:var(--font-ui,system-ui,-apple-system,"Segoe UI",Roboto,"PingFang SC","Microsoft YaHei",sans-serif);color:#000;}
.print-doc h2{font-size:15px;font-weight:700;margin:16px 0 4px;text-align:center;letter-spacing:2px;}
.print-doc .p-cls-count{font-size:11.5px;color:#555;margin-bottom:2px;text-align:center;}
.print-doc table td.c{text-align:center;}
.print-doc table tr.p-empty td{color:#888;}
.print-doc h1{font-size:20px;text-align:center;letter-spacing:3px;margin-bottom:8px;font-weight:700;}
.print-doc .p-sub{text-align:center;font-size:12px;color:#444;margin-bottom:18px;}
.print-doc .p-meta{font-size:13px;line-height:2.1;margin-bottom:14px;}
.print-doc .p-meta span{display:inline-block;min-width:47%;}
.print-doc .p-meta b{font-weight:600;display:inline-block;min-width:74px;}
.print-doc p{font-size:13.5px;line-height:2;text-indent:2em;margin:10px 0;}
.print-doc .p-sign{margin-top:38px;text-align:right;font-size:13.5px;line-height:2.2;}
.print-doc table{width:100%;border-collapse:collapse;margin:14px 0;font-size:12.5px;}
.print-doc table th,.print-doc table td{border:1px solid #000;padding:6px 8px;}
.print-doc table th{background:#f2f2f2;font-weight:600;text-align:center;}
.print-doc .p-foot{margin-top:26px;font-size:11px;color:#666;text-align:center;border-top:1px dashed #999;padding-top:8px;}

@media print{
  body>*{display:none !important;}
  #printRoot{display:block !important;}
  .print-root{position:static;background:#fff;padding:0;margin:0;}
  .print-doc{width:100%;padding:0;}
  @page{margin:18mm 16mm;}
}

/* ---------- 响应式 ---------- */
@media(max-width:860px){
  /* 侧栏变成抽屉：默认移出屏幕，点顶栏 ☰ 唤出（open 类由 app.js 维护） */
  .nav-toggle{display:inline-flex;}
  .sidebar{
    position:fixed;left:0;top:0;bottom:0;z-index:900;
    width:min(280px,82vw);transform:translateX(-100%);transition:transform .2s;
  }
  .sidebar.open{transform:none;box-shadow:var(--shadow-3);}
  .form-grid{grid-template-columns:1fr;}
  .page{padding:14px 12px 40px;}
  .topbar{padding:0 12px;}
}

/* ---------- 微信绑定页 ---------- */
.card-head .ch-left{flex:1;display:flex;align-items:center;gap:10px;}
.card-head .ch-right{display:flex;align-items:center;gap:8px;}
.qr-box{display:flex;justify-content:center;padding:10px 0;}
.qr-img{width:240px;height:240px;border:1px solid var(--c-border);border-radius:10px;background:#fff;}
.bind-state{display:flex;align-items:center;gap:14px;padding:14px 16px;background:var(--c-green-soft);border:1px solid #bbf7d0;border-radius:var(--radius);}
.bs-ico{font-size:30px;line-height:1;}
.bs-title{font-size:15px;font-weight:700;}
.bs-sub{font-size:12.5px;color:var(--c-text-2);margin-top:2px;}
.qr-box img{max-width:100%;}

/* ---------- 个人中心：只读信息行 ---------- */
.kv{
  display:flex;align-items:baseline;gap:12px;
  padding:9px 0;border-bottom:1px dashed var(--c-border);
}
.kv:last-child{border-bottom:none;}
.kv-k{flex:0 0 88px;font-size:13px;color:var(--c-text-2);}
.kv-v{flex:1;font-size:13.5px;word-break:break-all;}
@media (max-width:520px){
  .kv{flex-direction:column;gap:2px;}
  .kv-k{flex:none;}
}

/* ---------- 学生管理：按年级分栏 + 班级显隐 ---------- */
.grade-band{
  border:1px solid var(--c-border);border-radius:var(--radius);
  background:var(--c-surface-2);margin-bottom:14px;overflow:hidden;
}
.grade-band:last-child{margin-bottom:0;}
.grade-band-head{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:9px 12px;border-bottom:1px solid var(--c-border);background:#fff;
}
.grade-band-title{font-size:13.5px;font-weight:700;}
.grade-band-meta{font-size:12px;color:var(--c-text-2);}
.grade-band-acts{margin-left:auto;display:flex;gap:6px;align-items:center;flex-wrap:wrap;}
/* 年级内同年级班级横排：用户要求每行最多两个班（2026-10-13），
   原来 auto-fill 在宽屏下会排到三四个，表格被挤扁；窄屏单列见下方 860px 媒体查询。 */
.cls-grid{
  display:grid;gap:12px;padding:12px;align-items:start;
  grid-template-columns:repeat(2,minmax(0,1fr));
}
.cls-box{
  background:#fff;border:1px solid var(--c-border);border-radius:var(--radius-sm);
  overflow:hidden;box-shadow:var(--shadow-1);min-width:0;
}
.cls-head{
  display:flex;align-items:center;gap:8px;padding:8px 10px;
  border-bottom:1px solid var(--c-border);background:var(--c-surface-2);
}
.cls-name{font-size:13px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.cls-count{font-size:11.5px;color:var(--c-text-2);white-space:nowrap;}
/* 班内搜索框（2026-10-16 用户要求）：跟在「打印」按钮之后、靠右排。
   「打印」原本用 margin-left:auto 推到右侧；搜索框紧跟在它后面，
   两者之间补一点间隙，不要让输入框贴住按钮。 */
.cls-head .cls-search{flex:none;}
.cls-head .cls-search .inp{width:210px;height:30px;font-size:12.5px;}
.cls-head .cls-search .btn-sm{margin-left:6px;}
.cls-hide{
  margin-left:auto;border:none;background:transparent;color:var(--c-text-3);
  cursor:pointer;font-size:11.5px;padding:2px 6px;border-radius:5px;white-space:nowrap;
}
.cls-hide:hover{background:var(--c-red-soft);color:var(--c-red);}
/* 班内名单限高滚动，避免一个 40 人的班把整页撑得很长 */
.cls-tbl-wrap{max-height:400px;overflow:auto;}
/* 「我的班级」点展开后把小窗放开：整班学生一次看完，不再内部滚动。
   名单加了 延时/所在社团/家长电话/备注 后列较多，宽度不够时改成**横向滚动**，
   别把列挤扁（2026-10-14）。 */
.cls-tbl-wrap.is-open{max-height:none;overflow-x:auto;overflow-y:visible;}
/* 展开名单的班卡片占满整行；收起的仍保持每行两个班（2026-10-14 用户要求两个并排，别丢） */
.cls-grid>.cls-box.is-wide{grid-column:1 / -1;}
.cls-box.is-folded{padding-bottom:10px;}
.cls-tbl-wrap table.tbl{font-size:12.5px;}
.cls-tbl-wrap table.tbl th{padding:7px 8px;}
.cls-tbl-wrap table.tbl td{padding:6px 8px;}
.cls-nm{max-width:96px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* 被隐藏的班级：以虚线胶囊留在年级条里，点一下恢复 */
.restore-list{display:flex;gap:6px;flex-wrap:wrap;padding:10px 12px;border-top:1px dashed var(--c-border-strong);}
.restore-list .lead{font-size:12px;color:var(--c-text-3);align-self:center;}
.restore-chip{
  display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:20px;
  font-size:12px;background:#fff;border:1px dashed var(--c-border-strong);
  color:var(--c-text-2);cursor:pointer;
}
.restore-chip:hover{border-color:var(--c-primary);color:var(--c-primary);background:var(--c-primary-soft);}
/* 班级显示设置弹窗 */
.cls-toggle-list{display:flex;flex-direction:column;gap:1px;max-height:440px;overflow:auto;}
.cls-toggle-row{
  display:flex;align-items:center;gap:9px;padding:7px 8px;
  border-radius:var(--radius-sm);font-size:13px;
}
.cls-toggle-row:hover{background:var(--c-surface-2);}
.cls-toggle-row .nm{flex:1;min-width:0;}
.grade-pick{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px;}
@media(max-width:860px){
  .cls-grid{grid-template-columns:1fr;}
}

/* ==================== 二级权限（只读） ==================== */
/* 二级权限可以看到超级权限的全部页面，但页面内所有写操作按钮置灰。
   数据层还有 store.canWrite() 兜底 —— 即使绕过样式，也写不进去。 */
.ro-banner{
  display:flex;align-items:center;gap:9px;margin:0 0 14px;
  padding:9px 13px;border-radius:var(--radius-sm);
  background:#fff7ed;border:1px solid #fdba74;
  color:#9a3412;font-size:12.5px;line-height:1.6;
}
.ro-banner .ro-dot{font-size:14px;flex:none;}
/* 二级权限说明（个人中心内，2026-10-15 从页面顶部横幅挪来） */
.staff-notice{margin:0 0 14px;padding:11px 14px;border-radius:var(--radius-sm);
  background:#fff7ed;border:1px solid #fdba74;color:#9a3412;font-size:12.8px;line-height:1.7;}
.staff-notice-title{font-weight:600;margin-bottom:3px;}
.staff-notice-text{font-size:12.8px;}
/* 2026-10-15：.tab / .chip 不再整类锁死 —— 它们是筛选 / 排序 / 视图切换标签，
   只影响「看哪部分数据」，不改数据；锁死会让只读权限连筛选都点不动。
   真正的写入口（按钮）依旧全锁，恢复芯片（restore-chip）涉及覆盖数据，保留锁死。 */
/* 2026-10-19 无障碍整改：原来用 pointer-events:none 做"假禁用"——只挡鼠标，
   键盘仍能 Tab 聚焦并 Enter 触发，状态与行为不一致（4.1.2）。
   现在由 JS（core.a11yScan）把这些按钮真正 disabled + aria-disabled，
   CSS 只负责禁用观感。 */
.page-readonly button:disabled,
.page-readonly .restore-chip[aria-disabled="true"]{
  opacity:.45;cursor:not-allowed;
}
/* 输入框 / 下拉仍可交互：搜索、筛选、切换学年学期都不改数据，
   只读权限也要能查得动，否则「能看」就变成了「看不全」。 */
.page-readonly input:disabled,
.page-readonly select:disabled{opacity:.5;}

/* ==================== 课表网格强化（2026-10-12） ==================== */
/* 课位文字水平居中（原来只垂直居中） */
.cell{align-items:center;text-align:center;}
.cell .c-sub,.cell .c-cls,.cell .c-tea,.cell .c-room{text-align:center;}
/* 网格线更清楚：竖线原来太淡被色块盖住，换 collapse + 全边框 */
table.sch{border-collapse:collapse;}
table.sch th,table.sch td{border:1px solid var(--c-border-strong);}
table.sch th:last-child,table.sch td:last-child{border-right:1px solid var(--c-border-strong);}

/* ==================== 学生情况一览表（工作台，2026-10-16） ==================== */
/* 原「今日课务安排」卡片替换为学生情况一览表：各班 男生/女生/在籍/实际 + 合计行。
   班级多（全校 37 个班）时限制高度内部滚动，合计行吸底。 */
.stu-overview-wrap{max-height:480px;overflow:auto;}
table.tbl.stu-overview th,table.tbl.stu-overview td{padding:6px 10px;white-space:nowrap;}
table.tbl.stu-overview .num{text-align:center;}
table.tbl.stu-overview tfoot td{position:sticky;bottom:0;background:#f1f5f9;font-weight:600;}
table.tbl.stu-overview tbody tr:hover{background:#f8fafc;}
/* 学籍异常两栏（2026-10-16）：默认表格 th 是 text-align:left，这里单独居左并允许换行，
   否则长名单会把整表撑得横向要滚很久。徽标自己内部截断，全名靠 title。 */
table.tbl.stu-overview th.stu-abn,table.tbl.stu-overview td.stu-abn{white-space:normal;min-width:96px;max-width:190px;}
table.tbl.stu-overview td.stu-abn .badge{display:inline-block;font-weight:500;line-height:1.5;text-align:left;white-space:normal;}

/* ==================== 我的班级（学生管理同款表格） ==================== */
/* 居中 + 全网格线，与「我的课表」视觉统一 */
table.mycls-tbl th,table.mycls-tbl td{text-align:center;border:1px solid var(--c-border);}
table.mycls-tbl th{white-space:nowrap;}
table.mycls-tbl td .btn{margin:0 2px;}

/* ==================== 课位文字居中（强化版，防止被缓存/覆盖） ==================== */
table.sch .cell{align-items:center !important;text-align:center !important;}
table.sch .cell .c-sub,
table.sch .cell .c-cls,
table.sch .cell .c-tea,
table.sch .cell .c-room{text-align:center !important;}
table.sch td.period-col{text-align:center !important;}

/* ==================== 科目颜色开关 ==================== */
/* 关闭时格子全部白底（格子底色是内联 style，必须 !important 覆盖），
   网格线保留，靠文字仍能区分科目 */
.sch-wrap.no-color .cell{background:#ffffff !important;}
.sch-wrap.no-color .cell:hover{background:#f8fafc !important;}
/* 开关按钮状态 */
.btn.btn-color-on{background:var(--c-teal-soft);border-color:#99f6e4;color:#0f766e;}

/* ==================== 课表边框（黑色） ==================== */
/* 用户要求：无色态下网格线与格子边框用黑色，区分更清楚 */
.sch-wrap.no-color table.sch th,
.sch-wrap.no-color table.sch td{border-color:#1f2937 !important;}
/* 格子自身不描边（隐藏框框），只留 td 网格线 */
.sch-wrap.no-color table.sch .cell{border:none !important;}

/* ==================== 课表中值行 ==================== */
/* 第4节（上午最后一节）与第5节之间的中值分隔行 */
table.sch tr.midday-row td.midday-cell{
  background:#fffbeb;padding:7px 10px;text-align:center;
  border:1px solid var(--c-border-strong);
}
.sch-wrap.no-color table.sch tr.midday-row td.midday-cell{border-color:#1f2937 !important;}
.midday-badge{
  display:inline-block;padding:2px 10px;border-radius:20px;margin-right:10px;
  background:#fef3c7;border:1px solid #fde68a;color:#92400e;
  font-size:12px;font-weight:600;
}
.midday-text{font-size:12.5px;color:#92400e;font-weight:600;}

/* ==================== 中值行（按天版） ==================== */
/* 每天一格显示当天中值安排：教师视角=管理的班级，班级视角=中值教师。
   居中必须写 !important：table.sch td 有自己的 vertical-align，且课表格子
   里的 .cell 是 flex 布局，普通继承会被覆盖，用户反馈过中值文字不居中。 */
table.sch tr.midday-row td.midday-cell{
  background:#fffbeb;padding:6px 8px;
  text-align:center !important;vertical-align:middle !important;
  border:1px solid var(--c-border-strong);
}
table.sch tr.midday-row td.midday-label{width:92px;white-space:nowrap;}
table.sch tr.midday-row td.midday-label .midday-badge{margin-right:0;}
/* 中值那一行的标签格也要固定在左侧：横向拖动课表（班级多、格子宽）时，
   节次列不动而中值格跟着跑，看起来就像「中值掉队了」——用户反馈过。
   与 .period-col 用同一套规则（sticky + left:0 + z-index:1），底色本身不透明，不会被压字。 */
table.sch tr.midday-row td.midday-label{position:sticky;left:0;z-index:1;}
table.sch tr.midday-row td.midday-day{
  font-size:12.5px;color:#92400e;font-weight:600;
  text-align:center !important;vertical-align:middle !important;
}
.midday-sub{display:block;font-size:10.5px;color:#b45309;font-weight:400;margin-top:1px;text-align:center !important;}
.sch-wrap.no-color table.sch tr.midday-row td.midday-cell{border-color:#1f2937 !important;}
/* 全校课表的中值行：班级列很宽，文字同样居中 */
table.sch tr.midday-row td{text-align:center !important;vertical-align:middle !important;}
/* 无色态：中值行跟着颜色开关一起去色（用户反馈：中值的颜色没受开关控制）。
   浅黄底、米黄徽章、棕色文字全部换成白底黑字，与课位格一致 */
.sch-wrap.no-color table.sch tr.midday-row td.midday-cell{background:#ffffff !important;}
.sch-wrap.no-color table.sch tr.midday-row td.midday-cell .midday-badge{
  background:#ffffff;border-color:#1f2937;color:#1f2937;
}
.sch-wrap.no-color table.sch tr.midday-row td.midday-cell .midday-sub{color:#1f2937;}
.sch-wrap.no-color table.sch tr.midday-row td.midday-cell .midday-text{color:#1f2937;}

/* ==================== 课表早读行（2026-10-20） ==================== */
/* 第 1 节之前的早读行：黛蓝软底（与中值的藤黄区分，一眼看出"一个在读、一个在管"） */
table.sch tr.early-row td.early-cell{
  background:#eef4fb;padding:6px 8px;
  text-align:center !important;vertical-align:middle !important;
  border:1px solid var(--c-border-strong);
}
table.sch tr.early-row td.early-label{width:92px;white-space:nowrap;position:sticky;left:0;z-index:1;}
table.sch tr.early-row td.early-label .early-badge{margin-right:0;}
table.sch tr.early-row td.early-day{
  font-size:12.5px;color:#1d4ed8;font-weight:600;
  text-align:center !important;vertical-align:middle !important;
}
.early-badge{
  display:inline-block;padding:2px 10px;border-radius:20px;margin-right:10px;
  background:#dbeafe;border:1px solid #bfdbfe;color:#1d4ed8;
  font-size:12px;font-weight:600;
}
table.sch tr.early-row td.early-cell .midday-sub{color:#1d4ed8;}
.sch-wrap.no-color table.sch tr.early-row td.early-cell{border-color:#1f2937 !important;background:#ffffff !important;}
.sch-wrap.no-color table.sch tr.early-row td.early-cell .early-badge{
  background:#ffffff;border-color:#1f2937;color:#1f2937;
}
.sch-wrap.no-color table.sch tr.early-row td.early-cell .midday-sub{color:#1f2937;}
.sch-wrap.no-color table.sch tr.midday-row td.midday-day{color:#1f2937 !important;}

/* ==================== 我的班级：范围切换（任教班级 / 全校班级） ==================== */
/* 超级权限与二级权限才出现：默认停「任教班级」，点「全校班级」才看全校 */
.seg{display:inline-flex;border:1px solid var(--c-border-strong);border-radius:7px;overflow:hidden;flex:none;}
.seg .btn{border:none;border-radius:0;height:27px;background:#fff;color:var(--c-text-2);}
.seg .btn + .btn{border-left:1px solid var(--c-border-strong);}
.seg .btn:hover{background:var(--c-surface-2);}
.seg .btn.on{background:var(--c-primary);color:#fff;font-weight:600;}
.seg .btn.on:hover{background:var(--c-primary-dark);}
.seg-sep{display:inline-block;width:1px;height:18px;background:var(--c-border);margin:0 2px;}

/* ==================== 我的班级（学生管理同款分组） ==================== */
/* 卡片头部的「新增学生」按钮靠右，班名过长时自动省略 */
.cls-head .cls-add{margin-left:auto;flex:none;}
/* 联系电话列窄一点，给姓名和操作留地方 */
.cls-tbl-wrap table.mycls-tbl td:nth-child(5),.cls-tbl-wrap table.mycls-tbl th:nth-child(5){white-space:nowrap;}

/* ==================== 我的班级 · 打印选班 ==================== */
/* 卡片头部的「打印」按钮靠右；与「新增学生」同时出现时紧贴（不撑开间隙） */
.cls-head .cls-print{margin-left:auto;flex:none;}
.cls-head .cls-print ~ .cls-add{margin-left:6px;}
/* 打印选班弹窗：按年级分带 + 同年级班级网格，与页面展示顺序一致 */
.print-pick{max-height:54vh;overflow-y:auto;padding-right:2px;}
.print-pick-band{margin-bottom:12px;}
.print-pick-band:last-child{margin-bottom:0;}
.print-pick-band-head{display:flex;align-items:center;gap:8px;margin-bottom:6px;}
.print-pick-band-head .t{font-size:12.5px;font-weight:700;}
.print-pick-band-head .n{font-size:11.5px;color:var(--c-text-2);}
.print-pick-band-head .acts{margin-left:auto;display:flex;gap:6px;}
.print-pick-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(158px,1fr));gap:6px;}
.print-pick-item{
  display:flex;align-items:center;gap:7px;border:1px solid var(--c-border);border-radius:7px;
  padding:7px 9px;cursor:pointer;background:#fff;transition:.12s;
}
.print-pick-item:hover{border-color:var(--c-primary);background:var(--c-primary-soft);}
.print-pick-item.sel{border-color:var(--c-primary);background:var(--c-primary-soft);}
.print-pick-item input{width:auto;margin:0;flex:none;}
.print-pick-item .n{font-size:12.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.print-pick-item .c{font-size:11px;color:var(--c-text-3);margin-left:auto;flex:none;}

/* ==================== 个人中心 · 界面字体 ==================== */
.font-pick{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:8px;}
.font-pick-item{
  border:1px solid var(--c-border);border-radius:8px;padding:9px 11px;cursor:pointer;
  background:#fff;text-align:left;transition:.13s;
}
.font-pick-item:hover{border-color:var(--c-primary);background:var(--c-primary-soft);}
.font-pick-item.sel{border-color:var(--c-primary);background:var(--c-primary-soft);box-shadow:0 0 0 2px rgba(37,99,235,.14);}
.font-pick-item .fn{font-size:12.5px;font-weight:700;}
.font-pick-item .fd{font-size:11px;color:var(--c-text-3);margin-top:1px;}
.font-pick-item .fs{font-size:14px;margin-top:5px;color:var(--c-text);line-height:1.5;}
.font-preview{
  margin-top:12px;border:1px dashed var(--c-border-strong);border-radius:8px;padding:12px 14px;
  background:var(--c-surface-2);
}
.font-preview .fp-t{font-size:12px;color:var(--c-text-2);margin-bottom:6px;}
.font-preview .fp-body{font-size:14.5px;line-height:1.9;}

/* ==================== 工作台 · 天气预报 ==================== */
.wx-now{display:flex;align-items:center;gap:14px;}
.wx-ico{font-size:36px;line-height:1;flex:none;}
.wx-temp{font-size:27px;font-weight:700;letter-spacing:.5px;line-height:1.1;}
.wx-temp small{font-size:12px;font-weight:500;color:var(--c-text-2);margin-left:3px;}
.wx-now-main{min-width:0;}
.wx-desc{font-size:13px;font-weight:600;}
.wx-sub{font-size:11.5px;color:var(--c-text-3);margin-top:2px;}
.wx-days{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;}
.wx-day{
  border:1px solid var(--c-border);border-radius:8px;padding:8px 4px;text-align:center;
  background:var(--c-surface-2);
}
.wx-day.is-today{border-color:var(--c-primary);background:var(--c-primary-soft);}
.wx-day .wd-name{font-size:11.5px;color:var(--c-text-2);}
.wx-day .wd-ico{font-size:18px;line-height:1;margin:4px 0 2px;}
.wx-day .wd-t{font-size:11.5px;font-weight:600;white-space:nowrap;}
.wx-day .wd-t .lo{color:var(--c-text-3);font-weight:400;}
/* 天气卡片「颜色：关」——与课表 no-color 同观感：去高亮、图标灰度化 */
.wx-card.no-color .wx-day.is-today{border-color:var(--c-border-strong);background:var(--c-surface-2);}
.wx-card.no-color .wx-ico,.wx-card.no-color .wx-day .wd-ico{filter:grayscale(1);opacity:.75;}
.wx-card.no-color .btn-color-on{border-color:var(--c-border-strong);box-shadow:none;}
/* 颜色：开 —— 低温数字用冷色，让卡片有色彩层次（关时回归灰） */
.wx-card:not(.no-color) .wx-day .wd-t .lo{color:var(--c-primary);}
.wx-msg{font-size:12.5px;color:var(--c-text-2);display:flex;align-items:center;gap:8px;}
.wx-src{font-size:11px;color:var(--c-text-3);margin-top:8px;}

/* ==================== 课后延时服务节次（适用年级） ==================== */
/* 只对指定年级显示的节次：在课表行头加角标，提示该节仅某些年级有 */
.period-grade-tag{
  display:inline-block;margin-left:4px;padding:0 5px;border-radius:4px;
  font-size:10px;font-weight:600;line-height:16px;vertical-align:1px;
  background:#ede9fe;color:#6d28d9;
}


/* ==================== 课后延时服务节次（适用年级） ==================== */
/* 节次管理里的「适用年级」多选 chips：不选=全校，选了只对这些年级显示 */
.grade-chips{display:flex;flex-wrap:wrap;gap:4px;}
.g-chip{
  border:1px solid var(--c-border);border-radius:20px;padding:2px 9px;
  font-size:11px;line-height:16px;cursor:pointer;background:#fff;color:var(--c-text-2);
  transition:.12s;
}
.g-chip:hover{border-color:var(--c-primary);color:var(--c-primary);}
.g-chip.on{background:var(--c-primary);border-color:var(--c-primary);color:#fff;font-weight:600;}

/* ==================== 可搜索下拉（教师姓名检索） ==================== */
/* 长名单（上百位教师）用键盘滚 select 太慢：输入中文或拼音首字母即时筛选。
   拼音缩写显示在每行右侧，提示「可以这样搜」。 */
.combo{position:relative;}
.combo-inp{padding-right:28px;}
.combo-clear{
  position:absolute;right:6px;top:50%;transform:translateY(-50%);
  border:none;background:none;cursor:pointer;padding:2px 4px;
  font-size:16px;line-height:1;color:var(--c-text-3);
}
.combo-clear:hover{color:var(--c-text);}
.combo-clear[hidden]{display:none;}
/* 列表挂 body + fixed：下拉在 .table-wrap（overflow:auto）里会被裁掉，
   只能看到两三位教师；fixed 后至少可显示 10 位（max-height 380 ≈ 12 项）。 */
.combo-list{
  position:fixed;z-index:2900;left:0;top:0;padding:4px;
  max-height:380px;min-width:180px;overflow-y:auto;
  background:#fff;border:1px solid var(--c-border);border-radius:8px;
  box-shadow:0 8px 24px rgba(15,23,42,.14);
}
.combo-list[hidden]{display:none;}
.combo-item{
  display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:6px;
  cursor:pointer;font-size:13px;color:var(--c-text);
}
.combo-item:hover{background:#f1f5f9;}
.combo-item.on{background:var(--c-primary-soft);}
.combo-item.is-cur{font-weight:700;}
.combo-item .ci-n{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.combo-item .ci-py{flex:none;font-size:11px;color:var(--c-text-3);letter-spacing:.5px;}
.combo-empty{padding:8px 10px;font-size:12.5px;color:var(--c-text-3);}
.combo-more{padding:6px 10px;font-size:11.5px;color:var(--c-text-3);}
/* 窄屏：下拉不超过屏幕 */
@media(max-width:560px){
  .combo-list{max-height:220px;}
}

/* ==================== 姓名下拉：分组标题 + 悬停课表预览 ==================== */
/* 代课候选按「空闲·同班级 / 同年级 / 其他年级」分组；鼠标悬停某位教师，
   右侧弹出他当天的课表，哪一节空着、哪一节有课一目了然。 */
.combo-group{
  padding:7px 9px 3px;font-size:11px;color:var(--c-text-3);
  border-top:1px dashed var(--c-border);margin-top:3px;
}
.combo-group:first-child{border-top:none;margin-top:0;}
.combo-tip{
  /* 挂在 body 上、fixed 定位：下拉在 .table-wrap（overflow:auto）里，
     浮层若留在容器内会被裁掉半截（预览课表显示不全）。
     位置由 JS 按 hover 行计算：贴右侧，放不下翻左侧、下方不够上移。 */
  position:fixed;left:0;top:0;z-index:3000;width:290px;
  max-height:calc(100vh - 24px);overflow-y:auto;
  background:#fff;border:1px solid var(--c-border);border-radius:10px;
  box-shadow:0 10px 30px rgba(15,23,42,.16);padding:10px 12px;
}
.combo-tip[hidden]{display:none;}
.td-card{font-size:12px;}
.td-head{display:flex;align-items:baseline;gap:6px;}
.td-head .td-name{font-weight:700;font-size:13px;}
.td-head .td-day{margin-left:auto;font-size:11px;color:var(--c-text-3);}
.td-meta{font-size:11px;color:var(--c-text-2);margin:3px 0 6px;}
.td-tbl{width:100%;border-collapse:collapse;}
.td-tbl td{padding:2px 0;vertical-align:top;border-top:1px solid #f1f5f9;}
.td-tbl tr:first-child td{border-top:none;}
.td-pname{white-space:nowrap;padding-right:8px !important;width:88px;}
.td-pn{color:var(--c-text-2);}
.td-pt{display:block;font-size:10.5px;color:var(--c-text-3);}
.td-free{color:var(--c-text-3);}
.td-busy{color:var(--c-text);}
.td-line{display:flex;gap:4px;align-items:baseline;}
.td-line .td-subj{font-weight:600;}
.td-line .td-cls{color:var(--c-text-2);font-size:11px;}
.td-line .td-mark{font-size:10px;color:#b45309;background:#fffbeb;border-radius:4px;padding:0 3px;}
/* 中值行：浅黄底，与课表里的中值行同一套视觉语言；被高亮时仍以高亮色为准 */
.td-tbl tr.is-midday td{background:#fffbeb;}
.td-tbl tr.is-midday .td-pn{color:#b45309;font-weight:600;}
/* 早读行（2026-10-20）：浅蓝底，与课表早读行同一视觉语言 */
.td-tbl tr.is-early td{background:#eef4fb;}
.td-tbl tr.is-early .td-pn{color:#1d4ed8;font-weight:600;}
.td-tbl tr.is-now{background:var(--c-primary-soft);}
.td-tbl tr.is-now .td-now,.td-tbl tr.is-now .td-pn{color:var(--c-primary);font-weight:700;}
.td-tbl tr.is-midday.is-now td{background:var(--c-primary-soft);}
@media(max-width:860px){ .combo-tip{width:248px;} }

/* 班级课表拖拽互换：拖起半透明、目标格虚线框 */
.cell.drag-src{opacity:.45;}
.cell.drag-over{outline:2px dashed var(--c-primary);outline-offset:-2px;background:var(--c-primary-soft);}
/* 中值槽（可点击修改 / 拖拽互换） */
td.midday-day.md-slot{cursor:pointer;}
td.midday-day.md-slot:hover{background:var(--c-primary-soft);}
td.midday-day.drag-src{opacity:.45;}
td.midday-day.drag-over{outline:2px dashed var(--c-primary);outline-offset:-3px;background:var(--c-primary-soft);}

/* 下拉列表固定行高（保证一屏能看到 10 位以上）；列表内搜索条已移除——主输入框本身就能过滤 */
.combo-items{padding:0 0 2px;}
.combo-item{min-height:30px;padding:6px 9px;}

/* =========================================================
   工作台「我的班级学生」内联编辑（2026-10-14 用户要求：可以直接填写）
   社团按时间段一行一个下拉，左侧是活动时间标签；电话/备注/延时也都是表内控件。
   ========================================================= */
table.tbl.stu-inline th{text-align:center;}   /* 2026-10-15 用户要求：表头与数据一样居中对齐（选择器须压过上面 table.tbl th 的 left） */
.stu-inline td{vertical-align:middle;text-align:center;}
.stu-inline td>.inp{max-width:172px;}
/* 社团格用三列网格：活动时间标签 | 社团下拉 | 「＋其他时间」按钮。
   · 按钮与社团框**同一行**、紧跟其后（2026-10-14 用户要求）；
   · 社团框宽度按内容自适应（max-content）⇒「航模社团（二年级）」这类 9 字名字能完整显示，
     配 max-width 上限防止将来出现超长名字把表格撑爆；
   · ⚠ 列宽写 max-content 不写 auto：auto 会把格子里剩下的宽度全吸走，标签列被撑得超宽。
   .stu-slot 用 display:contents，让标签与下拉直接成为网格项（is-hide 仍靠 display:none 生效）。 */
.stu-inline .stu-clubs{display:grid;grid-template-columns:max-content max-content max-content;gap:4px 6px;align-items:center;justify-content:center;}
.stu-inline .stu-slot{display:contents;}
.stu-inline .slot-tag{grid-column:1;font-size:11.5px;opacity:.72;border:1px solid var(--c-border);border-radius:5px;padding:2px 6px;white-space:nowrap;}
.stu-inline .stu-sel{grid-column:2;width:auto;min-width:0;max-width:260px;}
/* =========================================================
   教师工作台「天气 + 今日我的课表」两栏（2026-10-14）
   两张卡等高（grid 默认 stretch），内容较短的那张要**垂直居中**，
   否则课表挤在卡片顶部、下面一大片空白，看着"没居中对齐"。
   ========================================================= */
.two-col-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px;margin-bottom:16px;align-items:stretch;}
.two-col-row>.card{display:flex;flex-direction:column;min-width:0;}
.two-col-row>.card>.card-head{flex:0 0 auto;}
.two-col-row>.card>.card-body{flex:1 1 auto;display:flex;flex-direction:column;justify-content:center;}

/* 二级权限（staff）工作台的「个人 / 学校」切换标签（2026-10-15，默认个人） */
.dash-viewtabs{display:flex;gap:8px;align-items:center;}
.dash-viewtab{padding:7px 18px;border:1px solid var(--line,#e2e8f0);border-radius:8px;background:var(--card,#fff);
  color:var(--ink,#334);font-size:13.5px;cursor:pointer;}
.dash-viewtab:hover{border-color:var(--accent,#2563eb);color:var(--accent,#2563eb);}
.dash-viewtab.is-active{background:var(--accent,#2563eb);border-color:var(--accent,#2563eb);color:#fff;font-weight:600;}

/* ---------- 学校工作台顶部：指标 + 「统计与数据」横向快捷入口（2026-10-16） ----------
   指标行右侧原本空着（auto-fill 网格只填前 4 列），用户要求把侧栏
   「统计与数据」组五个入口横着排在那里。窄屏时自动换行成两行。 */
.dash-top-row{display:flex;gap:14px;align-items:stretch;flex-wrap:wrap;margin-bottom:16px;}
.dash-top-row .stat-grid{flex:1 1 520px;min-width:0;}
.dash-quicknav{flex:1 1 420px;display:flex;flex-direction:column;min-width:0;}
.dash-quicknav .card-head{padding:10px 14px;}
.dash-quicknav .card-head h3{font-size:13px;margin:0;}
.dash-quicknav-body{display:flex;flex-direction:row;flex-wrap:wrap;gap:8px;padding:0 14px 12px;align-content:center;flex:1 1 auto;}
.qn-item{display:inline-flex;align-items:center;gap:7px;padding:8px 13px;border:1px solid var(--line,#e2e8f0);
  border-radius:8px;background:#fff;cursor:pointer;font-size:13px;color:var(--ink,#334);white-space:nowrap;}
.qn-item:hover{border-color:var(--accent,#2563eb);color:var(--accent,#2563eb);}.qn-ico{font-size:15px;line-height:1;}

/* ---------- 界面字号（个人中心可调，2026-10-14） ----------
   JS 只给 <html> 打 data-uisize，具体倍数集中在这里，方便统一调整。
   页面全是 px，所以用 zoom 整体缩放而不是改根字号（px 不吃继承）。 */
html[data-uisize="sm"]{zoom:.9;}
html[data-uisize="md"]{zoom:1;}
html[data-uisize="lg"]{zoom:1.15;}
html[data-uisize="xl"]{zoom:1.3;}
/* 打印一律按 100% 输出：缩放会把名单挤到多一张纸，需要放大打印用打印窗口的「缩放」 */
@media print{ html[data-uisize]{zoom:1 !important;} }

/* 字号档位选择器（与「界面字体」并排放在个人中心） */
.size-pick{display:flex;gap:8px;flex-wrap:wrap;}
.size-pick-item{
  display:flex;flex-direction:column;align-items:center;gap:2px;min-width:78px;
  padding:8px 10px;border:1px solid var(--c-border);border-radius:var(--radius-sm);
  background:#fff;cursor:pointer;
}
.size-pick-item:hover{border-color:var(--c-primary);background:var(--c-primary-soft);}
.size-pick-item.sel{border-color:var(--c-primary);background:var(--c-primary-soft);box-shadow:0 0 0 2px rgba(37,99,235,.14);}
.size-pick-item .sn{font-weight:700;}
.size-pick-item .sp{font-size:10.5px;color:var(--c-text-3);}

/* 界面背景设置（个人中心，2026-10-16） */
.bg-pick{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px;}
.bg-pick-item{
  display:flex;flex-direction:column;align-items:center;gap:2px;min-width:96px;
  padding:8px 12px;border:1px solid var(--c-border);border-radius:var(--radius-sm);
  background:#fff;cursor:pointer;
}
.bg-pick-item:hover{border-color:var(--c-primary);background:var(--c-primary-soft);}
.bg-pick-item.sel{border-color:var(--c-primary);background:var(--c-primary-soft);box-shadow:0 0 0 2px rgba(37,99,235,.14);}
.bg-pick-item .bn{font-weight:700;font-size:13px;}
.bg-pick-item .bd{font-size:10.5px;color:var(--c-text-3);}
.bg-upload-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px;}
.bg-slider{display:flex;align-items:center;gap:10px;margin:8px 0;}
.bg-slider .bg-k{width:66px;flex:none;font-size:13px;color:var(--c-text-2);}
.bg-range{flex:1;min-width:120px;accent-color:var(--c-primary);}
.bg-slider .bg-v{width:48px;flex:none;text-align:right;font-size:12.5px;color:var(--c-text-3);}
.bg-preview{
  height:96px;margin-top:12px;border:1px solid var(--c-border);border-radius:var(--radius-sm);
  position:relative;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  font-size:12.5px;color:var(--c-text-3);
}
/* 预览要能真实反映「虚化 + 淡化」的效果（2026-10-19 用户反馈：这边预览不了虚化的样子）。
   原来只在 JS 里设一个 inline background-image，滑块怎么拖预览都不动。
   现在分三层：::before 铺图（按 --app-bg-blur 虚化，四边外扩 24px 免得模糊后边缘透出）、
   ::after 铺白蒙版（--app-bg-veil）、容器本身只放文字。
   两个滑块改的都是同一批 CSS 变量，预览与真实界面完全一致。 */
.bg-preview::before{
  content:'';position:absolute;left:-24px;right:-24px;top:-24px;bottom:-24px;
  background-image:var(--app-bg-image,none);
  background-size:cover;background-position:center;
  filter:blur(var(--app-bg-blur,6px));
}
.bg-preview::after{
  content:'';position:absolute;inset:0;
  background:rgba(255,255,255,var(--app-bg-veil,.58));
}
.bg-preview>*{position:relative;z-index:1;}

/* 学生表上方的排序条 + 「不上延时 → 回家」标记（2026-10-14 用户要求） */
.stu-sortbar{display:flex;align-items:center;gap:8px;margin:2px 0 9px;}
.stu-sortbar .stu-sortlabel{font-size:12.5px;opacity:.72;}
/* 学生表「编辑」开关（2026-10-15）：关＝整表只读文字，开＝表里直接填；状态记本机 */
.stu-edit{display:inline-flex;align-items:center;gap:7px;margin-left:auto;font-size:12.5px;color:var(--c-text-2);cursor:pointer;user-select:none;white-space:nowrap;}
.stu-edit:hover{color:var(--c-text-1);}
.stu-edit-cb{appearance:none;-webkit-appearance:none;width:34px;height:19px;border-radius:10px;background:var(--c-border);position:relative;margin:0;cursor:pointer;transition:background .15s;outline:none;vertical-align:middle;flex:none;}
.stu-edit-cb:checked{background:var(--c-primary);}
.stu-edit-cb::before{content:'';position:absolute;top:2px;left:2px;width:15px;height:15px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.2);transition:left .15s;}
.stu-edit-cb:checked::before{left:17px;}
/* 只读行：文字代替下拉 / 输入框，操作列留空 */
.stu-inline .stu-ro td{padding-top:5px;padding-bottom:5px;}
.stu-inline .stu-ro-delay{font-size:12.5px;opacity:.85;}
.stu-inline .stu-ro-club{font-size:12.5px;}
.stu-inline .stu-home{grid-column:1 / -1;display:inline-block;font-size:12.5px;opacity:.75;border:1px dashed var(--c-border);border-radius:5px;padding:2px 9px;white-space:nowrap;}
/* 学生表：只显示参加了的社团时段，「＋ 其他时间」展开其余时段（2026-10-14 用户要求） */
/* 默认：按钮另起一行（下面有多个社团框时，"再加一个时段"不该挤在第一行后面） */
.stu-inline .stu-addslot{grid-column:2 / -1;justify-self:start;align-self:center;padding:1px 7px;font-size:11.5px;opacity:.8;}
/* 只有一个社团框时：按钮跟它同一行、紧跟其后（用户要求的位置） */
.stu-inline .stu-clubs.is-inline-more .stu-addslot{grid-column:3;}
.stu-inline .stu-clubs>.muted{grid-column:1 / -1;font-size:11.5px;}
/* 一个社团都没有：占位文字只占第 1 列，按钮紧跟其后同一行（别被挤到下面去） */
.stu-inline .stu-clubs.is-empty>.muted{grid-column:1;justify-self:start;}
.stu-inline .stu-clubs.is-empty .stu-addslot{grid-column:2;}
/* 未参加的时段用 is-hide 隐藏（原地切换，不重绘页面） */
.stu-inline .stu-slot.is-hide{display:none;}

/* ==================== 登录页外观（2026-10-20 用户要求） ==================== */
/* 登录页可见标题 / 副标题：没配置时不占位（原版式不变） */
.login-brand-text{width:100%;text-align:center;}
.login-brand-text .lbt-title{
  font-family:var(--font-kai);font-size:20px;font-weight:600;color:var(--c-text);
  letter-spacing:.5px;line-height:1.4;
}
.login-brand-text .lbt-sub{
  font-size:12.5px;color:var(--c-text-2);margin-top:4px;line-height:1.6;
}

/* 系统设置 → 登录页：左表单 + 右实时预览 */
.lp-cols{display:grid;grid-template-columns:1.25fr .75fr;gap:20px;align-items:start;}
@media (max-width:980px){.lp-cols{grid-template-columns:1fr;}}
.img-cur{display:flex;align-items:center;gap:10px;margin-top:8px;flex-wrap:wrap;}
.img-cur img{max-width:220px;max-height:64px;object-fit:contain;border:1px solid var(--c-border);border-radius:var(--radius);background:#fff;padding:3px;}

/* 预览：一张小号的登录卡 */
.login-preview{border:1px solid var(--c-border);border-radius:var(--radius);padding:12px;background:var(--c-surface-2);}
.lp-card{
  background:#fff;border:1px solid var(--c-border);border-radius:var(--radius);
  padding:16px 14px;box-shadow:var(--shadow-1);background-size:cover;background-position:center;
}
.lp-brand{text-align:center;margin-bottom:14px;}
.lp-logo{max-width:100%;max-height:56px;object-fit:contain;margin:0 auto 6px;display:block;}
.lp-logo-ph{
  width:56px;height:56px;border-radius:50%;background:var(--c-primary-soft);color:var(--c-primary);
  display:flex;align-items:center;justify-content:center;font-size:11px;margin:0 auto 6px;
}
.lp-title{font-family:var(--font-kai);font-size:15px;font-weight:600;color:var(--c-text);}
/* 取色器：系统设置 → 登录页 → 标题区样式 */
.lp-color{width:54px;height:30px;padding:2px;cursor:pointer;}
.lp-range{width:180px;max-width:100%;accent-color:var(--c-primary);cursor:pointer;}
.lp-opval{min-width:44px;text-align:center;font-size:13px;font-variant-numeric:tabular-nums;color:var(--c-text-2);}
/* 预览里的标题框（对应线上 .login-brand-text） */
.lp-titlebox{display:inline-block;max-width:100%;}

.lp-sub{font-size:11.5px;color:var(--c-text-2);margin-top:2px;}
.lp-field{height:26px;border:1px solid var(--c-border-strong);border-radius:var(--radius);margin-bottom:8px;padding:0 8px;display:flex;align-items:center;font-size:12px;color:var(--c-text-3);background:#fff;}
.lp-hint{margin-top:10px;font-size:11.5px;line-height:1.8;color:var(--c-text-2);
  font-family:var(--font-kai);text-align:left;}
.lp-hint b{color:var(--c-text);font-weight:700;}
.lp-btn{height:28px;border-radius:var(--radius);background:var(--c-primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:12.5px;font-family:var(--font-kai);}

/* ==================== 无障碍补做（2026-10-20，报告「需实测」两项） ==================== */
/* 2.4.11 焦点不被遮挡：粘性表头（top:0）与粘性首列（left:0）会盖住被 Tab 到的元素，
   浏览器把焦点滚进可视区后，焦点环正好落在粘性栏下面看不见。
   做法：给可聚焦元素加 scroll-margin，滚动时预留出粘性栏的高度 / 宽度。 */
table.tbl th, table.tbl td,
table.sch th, table.sch td,
.cls-tbl-wrap th, .cls-tbl-wrap td,
.card-head, .topbar, .sidebar .nav-item{
  scroll-margin-top:56px;      /* 顶栏 + 粘性表头的高度 */
  scroll-margin-left:100px;    /* 粘性首列的宽度 */
}
/* 焦点落在粘性首列里时，焦点环画在内侧，避免被右侧内容压住 */
table.sch td:focus-visible,
table.tbl td:focus-visible,
.cls-tbl-wrap td:focus-visible{
  outline:2px solid var(--c-primary);outline-offset:-2px;
}
/* 1.4.10 重排（200% 缩放）：课表是宽内容，允许横向滚动，但必须
   ① 滚动容器可 Tab 聚焦（已做）；② 提供"单班 / 按教师 / 按场地"等替代视图（课表页已有）；
   ③ 表格容器在窄屏下不撑破页面 —— 用 min-width:0 + overflow:auto，避免整页出现双向滚动条。 */
.sch-wrap{overflow:auto;max-width:100%;}
.page, .card, .card-body{min-width:0;}
.main{min-width:0;}
@media (max-width:860px){
  /* 窄屏（含 200% 缩放后的等效宽度）：课表保留横向滚动，卡片不撑破 */
  .sch-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch;}
  .card{max-width:100%;}
}

/* ---------- 证明与申请（2026-10-20） ---------- */
.stat-entry{cursor:pointer;transition:border-color .12s,box-shadow .12s,transform .12s;}
.stat-entry:hover{border-color:var(--c-primary);box-shadow:0 2px 10px rgba(37,99,235,.12);}
.stat-entry:focus-visible{outline:2px solid var(--c-primary);outline-offset:2px;}
.stat-entry .v.v-sm{font-size:19px;}
td.ops{white-space:nowrap;}
td.ops .btn + .btn{margin-left:6px;}
.cert-gsnh{min-height:24px;padding:4px 2px;font-size:13px;color:var(--c-text);word-break:break-all;}
.seal-preview{width:96px;height:auto;max-height:96px;object-fit:contain;border:1px dashed var(--c-border);border-radius:8px;padding:4px;background:#fff;}

/* 在读证明打印版式 */
.cert-doc{max-width:640px;margin:0 auto;padding:32px 24px;font-family:"KaiTi","楷体","STKaiti",serif;color:#000;}
.cert-doc .cert-title{font-size:30px;font-weight:700;text-align:center;letter-spacing:.35em;margin:6px 0 26px;}
.cert-doc .cert-body{font-size:17pt;line-height:2.1;text-indent:2em;margin:0 0 10px;}
.cert-doc .cert-note{font-size:11pt;margin:6px 0 40px;text-indent:2em;}
.cert-doc .cert-stamp{position:relative;margin-top:36px;}
.cert-doc .cert-school{font-size:14pt;text-align:right;margin:0 8px 10px 0;}
.cert-doc .cert-date{font-size:12pt;text-align:right;margin:0 8px 0 0;}
.cert-doc .cert-school::after{content:"";display:block;border-bottom:2px dotted #000;margin-top:8px;}
.cert-doc .cert-seal{
  position:absolute;right:30px;bottom:-42px;width:118px;height:auto;
  opacity:.88;transform:rotate(-12deg);mix-blend-mode:multiply;pointer-events:none;
}
